我是node.js,express和JWT的新手。我在这里找到了类似的问题,但没有帮助。
我能够登录并将令牌存储在本地存储中,但是当我尝试为具有相同令牌的另一个请求设置授权标头时,它将无法在服务器中进行验证。我从服务器和客户端都检查了令牌,它们完全相同,但是验证失败,请帮忙!
这是我用来验证令牌的代码。
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"})
}
}
在app.js
文件中,我将verify
函数用于另一条路由。
const { verify } = require('./controllers/auth')
const userRoutes = require('./routes/userRoutes')
app.use('/user', verify, userRoutes)
我在哪里错了?
编辑:
我在console.log(e)
内的verify
函数中添加了catch()
,并得到了以下结果。
TokenExpiredError:jwt已过期 在/home/shashank/Documents/sms/server/node_modules/jsonwebtoken/verify.js:152:21 在getSecret(/home/shashank/Documents/sms/server/node_modules/jsonwebtoken/verify.js:90:14) 在Object.module.exports [作为验证](/home/shashank/Documents/sms/server/node_modules/jsonwebtoken/verify.js:94:10) 在export.verify(/home/shashank/Documents/sms/server/controllers/auth.js:62:23) 在Layer.handle [作为handle_request](/home/shashank/Documents/sms/server/node_modules/express/lib/router/layer.js:95:5) 在trim_prefix(/home/shashank/Documents/sms/server/node_modules/express/lib/router/index.js:317:13) 在/home/shashank/Documents/sms/server/node_modules/express/lib/router/index.js:284:7 在Function.process_params(/home/shashank/Documents/sms/server/node_modules/express/lib/router/index.js:335:12) 在下一个(/home/shashank/Documents/sms/server/node_modules/express/lib/router/index.js:275:10) 在cookieParser(/home/shashank/Documents/sms/server/node_modules/cookie-parser/index.js:57:14) {expiredAt:2020-10-29T17:30:31.000Z}
让我展示我的.env文件存储密钥信息的地方
ACCESS_TOKEN_SECRET=swsh23hjddnns
ACCESS_TOKEN_LIFE=3600
REFRESH_TOKEN_SECRET=dhw782wujnd99ahmmakhanjkajikhiwn2n
REFRESH_TOKEN_LIFE=86400
那么,访问令牌必须持续一个小时吗?
令牌的创建方式如下
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()
}
答案 0 :(得分:1)
您似乎遇到的问题是由于您如何存储超时期限。
摘自node-jsonwebtoken的文档
expiresIn:以秒或描述时间跨度的字符串表示 时代/毫秒。例如:60,“ 2天”,“ 10h”,“ 7d”。数值被解释 以秒为单位。如果您使用字符串,请确保您提供时间 单位(天,小时等),否则将使用毫秒单位 默认值(“ 120”等于“ 120ms”)。
因为要存储在process.env中,所以它看起来像是将其转换为字符串,而不是保持整数值。
测试代码:
const jwt = require('jsonwebtoken')
require('dotenv').config();
let payload = {email: 'email'}
let accessToken = jwt.sign(payload, process.env.ACCESS_TOKEN_SECRET, {
algorithm: "HS256",
expiresIn: process.env.ACCESS_TOKEN_LIFE
})
console.log(accessToken);
console.log('waiting 4 seconds');
setTimeout(function() {
let val = jwt.verify(accessToken, process.env.ACCESS_TOKEN_SECRET);
console.log(val);
}, 4000);
使用以下process.env值,它将失败
ACCESS_TOKEN_SECRET=swsh23hjddnns
ACCESS_TOKEN_LIFE=3600
REFRESH_TOKEN_SECRET=dhw782wujnd99ahmmakhanjkajikhiwn2n
REFRESH_TOKEN_LIFE=86400
但是,如果我们将ACCESS_TOKEN_LIFE更改为
ACCESS_TOKEN_LIFE=3600S
成功
没有时间单位,任何延迟超过3.6秒的请求都会出错。