I have this function on the express side:
// Register user login
exports.register_user = function(req, res) {
var portalID = req.body.portalID;
var companyName = req.body.companyName;
var password = req.body.password;
var password2 = req.body.password2;
var salt = bcrypt.genSaltSync(12);
var hash = bcrypt.hashSync(password, salt);
password = hash;
var params = {
TableName: "HouseAccounts",
Item: {
"portalID": portalID,
"companyName": companyName,
"points": 0,
"password": password,
}
}
res.sendStatus(200);
}
And this fetch on the front end:
function register() {
fetch("MyURL/register", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
"portalID": document.getElementById("portal-id").value,
"companyName": document.getElementById("company-name").value,
"password": document.getElementById("password").value,
"password2": document.getElementById("password2").value
})
}).then(function(response){console.log(response)});
}
On the express side I can receive the JSON that was sent through the POST and do stuff with that data. However, on my front end I am not receiving a response back from the express side. The connection times out and status is (failed) with error Uncaught (in promise) TypeError: Failed to fetch in the console.
Okay, the problem was I am working on AWS Cloud9 and my Public IP to access the API changed upon restarting the instance so the request was not reaching the server side at all.
Related
I am currently trying to create a login system with a Mongo Database, but it won't work when I try to fetch POST the login credentials to my express.js API via the Chrome Browser. Unlike in any browser itt works when I use the Insomnia Client. I personally think the problem is either in the header or middleware part of the code. I am grateful for every indication where my problem might be.
Code:
Login function:
async function login() {
const data = getUserDataEncrypted(); //gets username and password
await fetch(url + "/checkUser/login", {
method: "POST",
mode: 'cors',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
}).then(res => {
console.log(res.json());
});
}
Used Middleware:
require('dotenv').config();
const express = require("express");
const app = express();
const mongoose = require('mongoose');
app.use(require("cors")());
app.use(express.json());
app.use(require("morgan")("combined"));
Server Side:
router.post('/login', async (req, res) => {
try {
const user = await User.find({ username: req.body.username });
if (user[0].password === req.body.password) {
res.send({
message: "Successfull Login",
login: true
});
return;
} else {
res.send({
message: "Password incorrect",
login: false
});
return;
}
} catch (error) {
res.send({
message: error.message,
req: req.body
});
}
});
User Data:
async function getUserDataEncrypted() {
var username = document.getElementById("username").value;
var password = document.getElementById("password").value;
password = await SHA256Encyption(password);
const data = {
username: username,
password: password
}
return data;
}
Images:
In the login function, try to console.log the data from getUserDataEncrypted().
If its null or undefined try to use await.
await getUserDataEncrypted();
const data = getUserDataEncrypted(); //gets username and password
You need to do some basic debugging. If you had logged the value of data then the problem would be obvious.
getUserDataEncrypted is marked as async so it returns a promise.
console.log(JSON.stringify(Promise.resolve()));
Promises stringify to empty objects.
You need to await the promise or get (and use) its result in a then() callback.
I am trying to build an authentication system so, i used node , mysql,express for that so now i am simply saving and checking user exist in database can access but now i added JWT to it, so now i want this JWT token to store in localstorage or in cookies so, can someone guide me how can i do so
this is my authentication controller.js
var Cryptr = require('cryptr');
cryptr = new Cryptr('myTotalySecretKey');
var express = require('express');
const ap = express();
var jwt = require('jsonwebtoken');
var connection = require('./../config');
module.exports.authenticate = function (req, res) {
var email = req.body.email;
var password = req.body.password;
connection.query('SELECT * FROM users WHERE email = ?', [email], function (error, results, fields) {
if (error) {
res.json({
status: false,
message: 'there are some error with query'
});
} else {
if (results.length > 0) {
decryptedString = cryptr.decrypt(results[0].password);
if (password == decryptedString) {
jwt.sign({ email, password },
'secretkey',
{ expiresIn: '10days' },
(err, token) => {
console.log('token:' + token);
module.exports = token;
console.log(token);
res.redirect('/home.html');
}
);
} else {
res.redirect('/login.html');
console.log("Wrong Input");
}
}
else {
res.redirect('/login.html');
}
}
});
};
now i want to pass the token value to the local-storage or cookies so that i can restrict someone from acessing a page, i am reallly new to node js so any help would be appriciated
First I should notify you that do not put any secret things like password in jwt payload because the values of the payload could be accessed easily, you can try to copy paste a jwt in jwt.io site and see the payload.
set jwt in cookie like below, this will use express cookie method that does set Http Set-Cookie header:
res.cookie('jwt', generated_cookie)
.redirect('/home.html');
Also if you want to use localStorage you can set jwt in header and then in your code get the jwt from the header of login request and save it in localStorage and after that you should pass it as header in all other request, but this approach is a better solution for api calls like when you use react or vue ...
res.set({x-token: generated_token});
// In your code get
// get token from response
localStorage.setItem('token', token);
// now whenever calling api pass token as header
I show you one solution using jwt token, you choose another way:
Back-end file e.g. api.js
let jwt = require('jsonwebtoken')
let secret = 'yourSecret'; //secret key necessary to encode token
let Cryptr = require('cryptr');
let cryptr = new Cryptr('myTotalySecretKey');
module.exports = function(router,upload) {
function tokenAuth(req, res, next){
let token = req.body.token || req.body.query || req.headers['x-access-token']
if(token){
jwt.verify(token, secret, function(err,decoded){
if(err){
res.json({ authenticated: false, message:'Invalid token'})
} else {
req.decoded = decoded;
next()
}
})
} else {
res.json({success:false, message:'No token provided'});
}
}
router.post('/authenticate', function(req, res){
connection.query('SELECT * FROM users WHERE email = ?', [email], function (error, results, fields){
if(error) {
res.json({ success:false, message: err })
}
if(!results.length){
res.json({success:false, message:'User no found'})
} else if (results.length>0){
if(!req.body.password){
res.json({success:false, message:'Password was not provided'});
} else {
var validPassword = cryptr.decrypt(results[0].password);
if(validPassword === req.body.password){
res.json({success:false, message:'Incorrect password'})
} else {
var token = jwt.sign({username: results[0].username, email: results[0].email}, secret, {expiresIn: '24h'})
res.json({success:true, message:'You have logged in correctly!', token: token })
}
}
}
})
})
//If you want create a route for authenticated users for example comment posts, you can use our `tokenAuth function`
router.post('/post/comment',tokenAuth,function(req,res){
//access only for authenticated users
}
return router
}
This tokenAuth function we'll be use in paths restricted to authenticated users
server file e.g. server.js
const express = require('express');
const app = express();
const port = process.env.PORT || 80;
const http = require('http').Server(app);
const routes = require(path_to_api.js)(router);
app.use('/myApi', routes)
//***Here you should implement more details about your project such as routes, body parsers and other middlewares*****//
//Connect to your database
http.listen(port, ()=> console.log(`Server running on ${port}`))
Front-end file e.g. controller.js
function(login){
return fetch('/myApi/authenticate',{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(login)
}).then(result=>result.json()).then(data=> window.localStorage.setItem('token', data.token))
}
//`login` argument should be an object and should be like {username: 'user username', password: 'user password'}
In order to make a user store cookies, you can use the Set-Cookie header. From MDN:
Set-Cookie: <cookie-name>=<cookie-value>
In order to pass a header using Express, you can use res.set(), e.g. res.set("Set-Cookie", "Token=" + token). I also suggest you use the HttpOnly cookie directive, since it seems from your post that you don't access this token directly via Javascript and you simply want to check it when the client requests a webpage: res.set("Set-Cookie", "Token=" + token + "; HttpOnly").
The client will send the Cookie header to you when it requests a resource. You can check this header using req.header('Cookie'), and the output will be "Token=<token>" if the user is authenticated. You can then check this token for authenticity.
I'm trying to use Node JWT Authentication API to build a local API using the following git: https://github.com/cornflourblue/node-role-based-authorization-api
the server listens in 4000 port, but it returns me the error 'Invalid token'. why is this happening?
I have the version 1.17.5
const config = require('config.json');
const jwt = require('jsonwebtoken');
// users hardcoded for simplicity, store in a db for production applications
const users = [{ id: 1, username: 'test', password: 'test', firstName: 'Test', lastName: 'User' }];
module.exports = {
authenticate,
getAll
};
async function authenticate({ username, password }) {
const user = users.find(u => u.username === username && u.password === password);
if (user) {
const token = jwt.sign({ sub: user.id }, config.secret);
const { password, ...userWithoutPassword } = user;
return {
...userWithoutPassword,
token
};
}
}
async function getAll() {
return users.map(u => {
const { password, ...userWithoutPassword } = u;
return userWithoutPassword;
});
}
Use Postman to send a POST(this is important. It should be POST) request to localhost:4000/users/authenticate. In the Body Tab change "form-data" to "raw" and type:
{
"username":"admin",
"password":"admin"
}
You will get token. Copy it.
Result of the POST request
Open a new tab to make a new GET request to localhost:4000/users/. On the Headers tab of Postman enter "Authorization" in the key field and 'bearer [token you copied]' to Value field. Make the request. It should return json with users.
Result of the GET request
Hello I am working on node application in which I am working on jsonwebtokens,passport-jwt.I created application backend side and working fine on postman but I stuck on front end side. when i send token in headers in postman then token based page open on postman fine but on front side display unauthorized.How can i send token in header so that this page also open on front end side.
My code:
app.post("/login", function(req, res) {
if(req.body.name && req.body.password){
var name = req.body.name;
var password = req.body.password;
}
var user = users[_.findIndex(users, {name: name})];
if( ! user ){
res.status(401).json({message:"no such user found"});
}
if(user.password === req.body.password) {
// from now on we'll identify the user by the id and the id is the only personalized value that goes into our token
var payload = {id: user.id};
var token = jwt.sign(payload, jwtOptions.secretOrKey);
//res.json({message: "ok", token: token});
res.redirect('/secret')
} else {
res.status(401).json({message:"passwords did not match"});
}
});
app.get("/secret", passport.authenticate('jwt', { session: false }), function(req, res){
res.json("Success! You can not see this without a token");
});
Where am i doing wrong??
in your /login you can save them tokens in a sessionStorage for future use...
something like this
if(user.password === req.body.password) {
....
var payload = {id: user.id};
var token = jwt.sign(payload, jwtOptions.secretOrKey);
req.session.token = token ;
}
}
use this session to update sessionStorage on client side
here is an article that is what you need for keeping logged in post login...
also you need to destroy the cookies on Logout
if you are getting token,you can send it as:
**
let headers = new Headers({ 'Content-Type': 'application/json',
'Authorization': 'Bearer ' + this.token });
**
I am creating a basic friend request feature. This is one of the function I am working on, when Ajax send the post request it shows 404. It works if I put the code directly in the server.js file but I am trying to organize the code. Any solution? Thanks!
client.pug make a ajax request when user add friend by using email and hit submit
$('#addFriend').on('click', function(ev) {
ev.preventDefault();
var searchByEmail = $('#searchByEmail').val();
$.ajax({
type: 'POST',
url: '/add',
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
data: {
email: searchByEmail
},
success: function(data) {
console.log('success');
}
});
document.getElementById("searchByEmail").value = "";
$('#userModal').modal('hide'); });
controllers/friend.js
const express = require('express');
const app = express();
const User = require('../models/user');
const bodyParser = require('body-parser');
var friendRequest = function() {
app.post('/add', function(req, res) {
var requestToEmail = req.body.email;
console.log(requestToEmail);
User.findOne({
email: requestToEmail
}, function(err, email) {
if (!email) {
console.log('cannot find the email', err);
return res.send(err);
}
/*
Add into database
Display the friend list
*/
})
});
} // End friend request
module.exports = friendRequest;
server.js include and use the module
const friendInvite = require('./controllers/friend');
app.use('/friend', friendInvite);
file structure
- server.js
- controllers
- friend.js
- views
- client.pug
Try change your code on controllers/friend.js like below :
const express = require('express');
const app = express();
const User = require('../models/user');
const bodyParser = require('body-parser');
var friendRequest = function() {
app.post('/add', function(req, res) {
var requestToEmail = req.body.email;
console.log(requestToEmail);
User.findOne({
email: requestToEmail
}, function(err, email) {
if (!email) {
console.log('cannot find the email', err);
return res.send(err);
}
/*
Add into database
Display the friend list
*/
//add this response to client side
res.json({ 'status': '200', 'desc': 'Success' });
})
});
} // End friend request
module.exports = friendRequest;
you must send response to client side what is sign if the data has saved.
maybe you can try to check snippets code here :
https://github.com/egin10/node_mongoose/blob/master/routes/student.js
I didn't see response in your app.post()
So it will be 404(Not found).
When you find a User, you can response something.
For example, a 'success' message and friend list.
app.post('/add', function(req, res) {
res.json(['success', friend list]);
});