In the express-jwt docs there is a reference to being able to use a getToken function to get the token from a request.
How do you use this call in a route?
app.use(jwt({
secret: 'hello world !',
credentialsRequired: false,
getToken: function fromHeaderOrQuerystring (req) {
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
return req.headers.authorization.split(' ')[1];
} else if (req.query && req.query.token) {
return req.query.token;
}
return null;
}
}));
A useful little trick is to add unless which makes every URL except those specified by unless require a token.
This means you don't need to create a app.get for every single path in your api that you want to protect (unless you want different secrets for each, which I don't know why you would).
var jwt = require('jsonwebtoken');
var expressJWT = require('express-jwt');
app.use(
expressJWT({
secret: 'hello world !',
getToken: function fromHeaderOrQueryString (req) {
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer')
return req.headers.authorization.split(' ')[1];
else if (req.query && req.query.token)
return req.query.token;
return null;
}
}).unless({ path: ['/login'] }));
// Test paths
app.get('/login', function (req, res) {
res.send("Attempting to login.");
});
app.get('/otherurl', function (req, res) {
res.send('Cannot get here.');
});
Or you simply specify it for a single path:
app.get('/protected',
expressJWT({
secret: 'hello world !',
getToken: function fromHeaderOrQueryString (req) {
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer')
return req.headers.authorization.split(' ')[1];
else if (req.query && req.query.token)
return req.query.token;
return null;
}
}));
Notice the change from get and use in the configuration.
For every path that you supply through express-jwt, the function getToken is run if specified in your configuration.
What's nice about adding unless is that now you have minimized the amount of work you need to do in order to get the token from the user for each and every path.
Refer to index.js of express-jwt which tells you more about how getToken works:
If you specify the option as a function, the token value is the returned value of the function
This means that you can supply custom logic for handling your tokens, and may be a useful place to call verify.
Otherwise it runs the standard logic for extracting the token from the Authorization header with the format of '[Authorization Bearer] [token]' (I denote the brackets to show where it splits the string).
Like so:
app.get('/protected',
jwt({
secret: 'hello world !',
credentialsRequired: false,
getToken: function fromHeaderOrQuerystring(req) {
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
return req.headers.authorization.split(' ')[1];
} else if (req.query && req.query.token) {
return req.query.token;
}
return null;
}
})
);
Just add the getToken field in the object you pass to the jwt middleware. It's a combination of the example in the question, and the first example in the documentation.
Another way to get a JWT and Bearer tokens is:
To get a JWT token
let token = req.headers.authorization && req.headers.authorization.match(/^JWT (.*)$/);
if (token && token[1]) { token = token[1]; }
if (!token) { throw ['missingRequired']; }
To get a Bearer token
let token = req.headers.authorization && req.headers.authorization.match(/^Bearer (.*)$/);
if (token && token[1]) { token = token[1]; }
if (!token) { throw ['missingRequired']; }
To support both types of tokens:
let token = req.headers.authorization
&& (
req.headers.authorization.match(/^JWT (.*)$/)
||
req.headers.authorization.match(/^Bearer (.*)$/)
);
if (token && token[1]) { token = token[1]; }
if (!token) { throw ['missingRequired']; }
Related
I am writing a post request with basic auth in node js.I am trying to hit API without authorization field in header, still I am not getting any error.
subscriptionRouter.route('/subscriptions')
.post((req, res) => {
//console.log(JSON.stringify(req.body));
if (!req.headers.authorization || req.headers.authorization.indexOf('Basic ') === -1) {
res.status(401).json({ message: 'Missing Authorization Header' });
}
const base64Credentials = req.headers.authorization.split(' ')[1];
const credentials = Buffer.from(base64Credentials, 'base64').toString('ascii');
if(credentials == 'GsubNode:WelcomeNode#123'){
console.log(req.body);
var msgId = putMessageSync(req.body);
let responseJSON = {};
if (msgId == "") {
responseJSON.statusCode = 400;
responseJSON.statusDesc = "Bad Request";
responseJSON.msgId = msgId;
}
else {
responseJSON.statusCode = 200;
responseJSON.statusDesc = "Posted";
responseJSON.MsgId = msgId;
}
res.json(responseJSON);
}
else{
res.status(401).json({ message: 'Invalid Authentication Credentials' });
}
})
You may want to use a middleware, first declare the function:
function authenticate(req, res, next){
const authHeader = req.headers['authorization'];
const base64Credentials = authHeader && authHeader.split(' ')[1];
if( base64Credentials == null ) return res.sendStatus(401)
if(credentials == 'GsubNode:WelcomeNode#123'){
next()
}
}
Then you'd specify the middleware for each path you'd like to authenticate and run the rest of your code for the api call (using express) like:
express.post('/subscriptions', authenticate, (req, res) => {
console.log(req.body);
var msgId = putMessageSync(req.body);
let responseJSON = {};
if (msgId == "") {
responseJSON.statusCode = 400;
responseJSON.statusDesc = "Bad Request";
responseJSON.msgId = msgId;
}
else {
responseJSON.statusCode = 200;
responseJSON.statusDesc = "Posted";
responseJSON.MsgId = msgId;
}
res.json(responseJSON);
});
EDIT: The answer to this post elaborates on routers and middleware: setting up a middleware in router.route() in nodejs (express)
I am trying to check if there is token but the 'split' is undefined. I'm still learning MERN so idk what's the problem.
const auths = async (req,res,next) => {
try {
const token = req.headers.authorization.split(" ")[1];
const isCustomAuth = token.length < 500;
let decodedData;
if(token && isCustomAuth){
decodedData = jwt.verify(token, 'todo');
req.userId = decodedData?.id;
}else {
decodedData = jwt.decode(token);
req.userId = decodedData?.sub;
}
next();
console.log('auth tapped!');
} catch (error) {
console.log(error);
}
}
Because header don't have authorization. So req.headers.authorization is undefined. You can use optional chaining to fix issues like this:
const token = req.headers.authorization?.split(" ")[1];
const User = require ('../models/User');
const jwt = require ('jsonwebtoken');
const asynchronous = require('./async');
const ErrorHandler = require ('..utils/errorHandler');
exports.protect = asynchronous(async (res,req,next)=> {
if(req.headers.authorization &&
req.headers.authorization.startsWith('Bearer') ) {
let token = req.headers.authorization.split(' ')[1]
}
if(!token) {
return next(new ErrorHandler('Unauthorized,401'))
}
try {
const tokenVerify = jwt.verify(token,process.env.SECRET)
req.user = await User.findById(decoded.id);
next();
} catch(err) {
return next(new ErrorHandler('Unauthorized,401'))
}
})
Hello good people please can you tell me why anytime I execute the above code in Postman,I get a typeError:cannot read property 'authorization' of undefined?
I have require protect in all the necessary routers
It's simple you have invert req and res ;)
req is before res in the prototype
the order would be (req,res) rather than (rea,req).
Im getting a JWT from Auth0. I can decode it with the following middleware function on my Node server (using https://www.npmjs.com/package/jwt-node)
function authoriseToken(req, res, next) {
const token = req.headers.authorization.replace('Bearer ', '');
const decodedToken = jwt.decode(token);
console.log('decodedToken ', decodedToken);
next();
}
How can I verify the token? I keep getting an error JsonWebTokenError: invalid algorithm
function authoriseToken(req, res, next) {
const token = req.headers.authorization.replace('Bearer ', '');
const verifyedToken = jwt.verify(token, "my-secrete");
console.log('verifyedToken ', verifyedToken);
next();
}
Im not sure if I should be using a secrete or a jwksUri or what the difference is
Here is the actual token:
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6Ik16QkJRa1k0T0RRNE9VWTJORVZGT1VJNFFrSXpNRUZDT0RaQ01VSTBOVGN4TWpVeU1UYzNRdyJ9.eyJpc3MiOiJodHRwczovL25vbWFkZ3JvdXBzLmF1dGgwLmNvbS8iLCJzdWIiOiJhdXRoMHw1YjMxMDhkNjc4NzFkNTBkZTA0Njc2NWEiLCJhdWQiOiJTZkQyMEVPZVdRbHlnWXIwUHNXODdtYjd0OGFBOFI2NiIsImlhdCI6MTUzMDAxMzQwMCwiZXhwIjoxNTMwMDQ5NDAwLCJhdF9oYXNoIjoiUi1mRGc3SVRzUUdqemplX3VUR01RdyIsIm5vbmNlIjoiQnN-VmZxNzdtNERuaTJ1LjlIUVJlSEpzeHA4UjF2aDcifQ.CwZb6j3DshbD5M-OWBQpc10EIpAd3D-TuZTA1p7alePobSRVM7bE9Yzr5DIRyc2YUQZQ_OBwVLfFPq0pEBTWFYq2O43FJZ726xP1zK7Ty4PvAoLe4Cx6E0Ow8V8Ymo87XCIKX8J1ndg47q5glKzsnSMToutEWRZ2lnxJyirD4m4EwFykDF8DalA1sWvqnYXEwWraY3VLroqyZH2nkeLDcpcMdJ0tWwmzldwi7ym9OmegV5GBl7F6BgrZNIJfdoT88Rs4AKzogJyJuVQ1XlD7Up_nYlAKBmRMgkFt3t_4iq7pTkgdrWl1tXuJQsnmkkVH6_yffNYrWDnuirWwTCG4XQ
verify takes algorithms option in third parameter, adjust value with the correct one.
You can find it under applications > advanced settings > oauth > JsonWebToken Signature Algorithm
Expanding on Gabriel Bleu's answer here is my complete code:
const jwt = require('jsonwebtoken');
const pemCert = `-----BEGIN CERTIFICATE-----
// <<CERT CODE HERE>>
-----END CERTIFICATE-----`;
function authoriseToken(req, res, next) {
const token = req.headers.authorization;
// If there is no token user is not logged in
if (!token || token.length === 0) {
next();
return;
}
// If there is a token then add it to the res
const tokenCrop = token.replace('Bearer ', '');
const decodedToken = jwt.verify(tokenCrop, pemCert, { algorithm: 'RS256' });
const userId = decodedToken.sub.replace('auth0|', '');
req.authUserId = userId;
next();
}
module.exports = authoriseToken;
I want to find whether the user is authenticated 'jwt' inside middleware. Is there any way like req.isAuthenticated() similar to passportjs?
module.exports = function(app){
return function(req, res, next){
// How to implement the below step?
var isAuthenticated = app.use(jwt({secret: app.get('jwtTokenSecret')}))
if(isAuthenticated){
// do some logic
}
}
}
Yes there is!
1) You can use use the express-jwt module. Check out https://github.com/auth0/express-jwt
2) You can do it this way:
//get the authorization token from the request headers, or from a cookie
if (req.headers && req.headers.authorization) {
var parts = req.headers.authorization.split(' ');
if (parts.length == 2) {
var scheme = parts[0];
var credentials = parts[1];
if (/^Bearer$/i.test(scheme)) {
token = credentials;
}
}
}
else if(req.cookies && req.cookies.token)
{
token = req.cookies.token;
}
...
jwt.verify(token, config.secrets.session, function(err, decoded) {
//isAuthenticated is in here
});