How to set headers for json web token in expressjs? - javascript

Hello I am working on mock authentication in nodeJs using express framework.I am using passport-jwt and jasonwebtoken for authentication. I created api and working well on postman.But I stuck on front end side I am not able to use protected api's on front end side.In postman i send token using headers and it works well.But it does not work on front end side.How to send token and verify from front end side??
My code is:
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) {
var payload = {id: user.id};
var token = jwt.sign(payload, jwtOptions.secretOrKey);
res.json({message: "ok", token: token});
} else {
res.status(401).json({message:"passwords did not match"});
}
});
and if token is valid this post method should redirect to this page
app.get("/secret", passport.authenticate('jwt', { session: false }), function(req, res){
res.json("Success! You can not see this without a token");
});

npm install cookie-parser
var cookieParser = require('cookie-parser')
app.use(cookieParser())
app.use(function (req, res, next) {
var cookie = req.cookies.jwtToken;
if (!cookie) {
res.cookie('jwtToken', theJwtTokenValue,
{ maxAge: 900000, httpOnly: true });
} else {
console.log('let's check that this is a valid cookie');
// send cookie along to the validation functions...
}
next();
});

Related

How to set the token to local storage or cookies so that i can allow user to access certain web pages

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.

How to set authorization header in node js?

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 });
**

Get token decrypted data

I am struggling with how to get my user decrypted data for the current user, basicly everytime a user does login he get a token at the moment.
After i login i can capture a phote and send it to the server, following my code you guys can see that this request needs a token to work.
Basicly i have a problem related to my app.js(starting file) i try to set a app.use that needs a token for all the routes that comes after the register and login, like this:
app.use('/',require('./routes/index'));
app.use(jwtPermission);
router.use('/fotos',fotos);
my jwt permission file:
var jwt = require('jsonwebtoken');
var jwtConfig = require('../config/jwt');
module.exports = function(req, res, next) {
console.log("entered");
// check header or url parameters or post parameters for token
var token = req.body.token || req.query.token || req.headers['x-access-token'];
console.log(req.headers['x-access-token']);
// decode token
if (token) {
// verifies secret and checks exp
jwt.verify(token,jwtConfig.secret, function (err, decoded) {
if (err) {
return res.json({ success: false, message: 'Failed to authenticate token.' });
} else {
// if everything is good, save to request for use in other routes
req.decoded = decoded;
next();
}
});
} else {
// if there is no token
// return an error
return res.status(403).send({
success: false,
message: 'No token provided.'
});
}
}
router index(connection to authentication and fotos files)
var express = require('express');
var router = express.Router();
router.use(function timeLog(req, res, next) {
console.log('Time: ', Date());
console.log('Request Type:', req.method);
console.log('Request URL:', req.originalUrl);
next(); //passa a solicitação para a próxima função de middleware na pilha
});
router.use('/',require('./authentication'))
router.use('/fotos',require('./fotos'));
router.use(function(req,res,next){
return res.status(404).json({Error:"Invalid Url"});
})
module.exports = router;
when i point to /fotos it doesn't enter the jwtPermission as i want, what is wrong?
you can add your token validation middleware before function that handles some route. For example:
router.use('/fotos', jwtAuthentication, require('./fotos'));

Twitter Oauth Token_secret doesn't get returned

When i try to get an access token from twitter. i get the ouath token and oauth verifier but the token_secret remains undefined as it doesn't get added as param in my callback url. please help
var OAuth = require('oauth').OAuth;
var config = require('../config');
// Create the oauth object for accessing Twitter
var oauth = new OAuth(
config.request_token_url,
config.access_token_url,
config.consumer_key,
config.consumer_secret,
config.oauth_version,
config.oauth_callback,
config.oauth_signature_method
);
module.exports = {
redirectToTwitterLoginPage: function(req, res, next) {
const cookies = req.cookies;
// Ask Twitter for a request token
oauth.getOAuthRequestToken(function(error, oauth_token, oauth_token_secret) {
if (error) {
console.log(error);
res.send("Authentication failed!");
} else {
// Use the request token to take the client to Twitter's authentication page
res.setCookie('oauth_token', oauth_token, { httpOnly: true });
res.setCookie('oauth_token_secret', oauth_token_secret, { httpOnly: true });
res.redirect(config.authorize_url + '?oauth_token='+oauth_token, next);
}
});
},
authenticate: function(req, res, callback) {
// Check if the request token and temporary credential are there
if (!(req.cookies.oauth_token && req.cookies.oauth_token_secret && req.cookies.oauth_verifier)) {
return callback("Request does not have all required keys");
}
// Clear the request token cookies
res.clearCookie('oauth_token');
res.clearCookie('oauth_token_secret');
// Tell router that authentication was successful
callback();
}
};

Node.js - Express.js JWT always returns an invalid token error in browser response

I'm using node.js and express.js with the express-jwt module, and I have set up a simple HTTP server to test everything:
This is the node code involved:
app.set('port', process.env.PORT || 3000);
app.use(express.methodOverride());
app.use(allow_cross_domain);
app.use('/api', expressJwt({secret: '09qrjjwef923jnrge$5ndjwk'}));
app.use(express.json());
app.use(express.urlencoded());
app.use('/', express.static(__dirname + '/'));
app.use(function(err, req, res, next){
if (err.constructor.name === 'UnauthorizedError') {
res.send(401, 'Unauthorized');
}
});
app.get('login',function(req,res){
//...
jwt.sign(results.username+results.email, secret, { expiresInMinutes: 9000000000*9393939393393939393939 });
});
app.post('api/profile',function(req,res){
console.log(req.user); // this return undefined in console
res.send(req.user); // response is pending and dunno why it returns error in browser console
});
So once I open the /login URL I get logged in and I send the session token to api/post, which returns this response error in the browser console:
{"error":{"message":"invalid signature","code":"invalid_token","status":401,"inner":{}}}
I don't understand why this is happening, because the token stored in the front-end and the token in JWT are the same. What could be the reason for this error?
An example of headers POSTed to the api/post URL:
Here is an example
http://blog.auth0.com/2014/01/07/angularjs-authentication-with-cookies-vs-token/
var expressJwt = require('express-jwt');
var jwt = require('jsonwebtoken');
var SECRET = 'shhhhhhared-secret';
app.use('/api', expressJwt({secret: SECRET}));
app.post('/authenticate', function (req, res) {
//TODO validate req.body.username and req.body.password
//if is invalid, return 401
if (!(req.body.username === 'john.doe' && req.body.password === 'foobar')) {
res.send(401, 'Wrong user or password');
return;
}
var profile = {
first_name: 'John',
last_name: 'Doe',
email: 'john#doe.com',
id: 123
};
// We are sending the profile inside the token
var token = jwt.sign(profile, SECRET, { expiresIn: 18000 }); // 60*5 minutes
res.json({ token: token });
});
app.get('/api/protected',
function(req, res) {
res.json(req.user);
});
Also, make sure you don't put a : after bearer. E.g.
BAD! Authorization: Bearer: eyJ0eXAiOiI1NiJ9.eyJpZCMjEyNzk2Njl9.4eU6X1wAQieH
Prints "UnauthorizedError: jwt must be provided" to logs
Good Authorization: Bearer eyJ0eXAiOiI1NiJ9.eyJpZCMjEyNzk2Njl9.4eU6X1wAQieH

Categories

Resources