I am new to node.js, express and JWT. I found similar questions here but they didn't help.
I am able to login and store the token in local storage but when I try set Authorization header for another request with the same token, it fails verification in the server. I checked the token both from the server and client, they are exactly the same but the verification is failing, please help !
Here is the code I am using to verify the token.
exports.verify = function(req, res, next) {
let accessToken = req.headers.authorization
if (!accessToken){
return res.status(403).send()
}
let payload
try{
// Never makes it through this
payload = jwt.verify(accessToken, process.env.ACCESS_TOKEN_SECRET)
next()
}
catch(e){
return res.status(401).json({success: false, message: "token expired or invalid"})
}
}
Here in app.js file I use the verify function like this for another route.
const { verify } = require('./controllers/auth')
const userRoutes = require('./routes/userRoutes')
app.use('/user', verify, userRoutes)
Where am I going wrong here ?
EDIT:
I added console.log(e) in the verify function, inside the catch() and got the the below result.
TokenExpiredError: jwt expired at /home/shashank/Documents/sms/server/node_modules/jsonwebtoken/verify.js:152:21 at getSecret (/home/shashank/Documents/sms/server/node_modules/jsonwebtoken/verify.js:90:14) at Object.module.exports [as verify] (/home/shashank/Documents/sms/server/node_modules/jsonwebtoken/verify.js:94:10) at exports.verify (/home/shashank/Documents/sms/server/controllers/auth.js:62:23) at Layer.handle [as handle_request] (/home/shashank/Documents/sms/server/node_modules/express/lib/router/layer.js:95:5) at trim_prefix (/home/shashank/Documents/sms/server/node_modules/express/lib/router/index.js:317:13) at /home/shashank/Documents/sms/server/node_modules/express/lib/router/index.js:284:7 at Function.process_params (/home/shashank/Documents/sms/server/node_modules/express/lib/router/index.js:335:12) at next (/home/shashank/Documents/sms/server/node_modules/express/lib/router/index.js:275:10) at cookieParser (/home/shashank/Documents/sms/server/node_modules/cookie-parser/index.js:57:14) { expiredAt: 2020-10-29T17:30:31.000Z }
Let me show my .env file where I store the secret key info
ACCESS_TOKEN_SECRET=swsh23hjddnns
ACCESS_TOKEN_LIFE=3600
REFRESH_TOKEN_SECRET=dhw782wujnd99ahmmakhanjkajikhiwn2n
REFRESH_TOKEN_LIFE=86400
So, the access token has to last an hour right ?
The token is created like below
const jwt = require('jsonwebtoken')
// Not using a database right now.
let users = {
email: 'myemail@gmail.com',
password: 'password'
}
exports.login = function(req, res) {
let email = req.body.email
let password = req.body.password
// Simple validation !
if (!email || !password || users.email !== email || users.password !== password){
return res.status(401).json({success: false, message: "Incorrect username or password"})
}
//use the payload to store information about the user such as username, user role, etc.
let payload = {email: email}
//create the access token with the shorter lifespan
let accessToken = jwt.sign(payload, process.env.ACCESS_TOKEN_SECRET, {
algorithm: "HS256",
expiresIn: process.env.ACCESS_TOKEN_LIFE
})
//create the refresh token with the longer lifespan
let refreshToken = jwt.sign(payload, process.env.REFRESH_TOKEN_SECRET, {
algorithm: "HS256",
expiresIn: process.env.REFRESH_TOKEN_LIFE
})
//store the refresh token in the user array
users.refreshToken = refreshToken
//send the access token to the client inside a cookie
// res.cookie("jwt", accessToken, { httpOnly: true}) //secure: false, use this along with httpOnly: true in production
// res.setHeader('Authorization', accessToken);
res.json({
accessToken: accessToken,
success: true, message: "Authentication success"
});
res.send()
}