【发布时间】:2020-12-08 21:55:17
【问题描述】:
当我尝试在我的 node.js 服务器中使用私有 api 时遇到问题,这是我正在关注的过程
- 注册(如果用户没有帐户)或登录(已有帐户)。
- 它生成令牌并将它传递到标题
res.header('access_token': token) - 我复制此令牌并将其粘贴到我的私有 api 的标题部分(我现在使用邮递员对其进行测试),以验证用户是否已登录。
- 在我的路由中,我使用中间件将其私有化,验证用户是否可以使用资源
jwt.verify(authorization[1], process.env.SEED_AUTH)(SEED_AUTH 是存储在我的服务器中的令牌密码)
当我遇到错误时,中间件无法验证用户并向我抛出此错误jwt expired
这是我的路线
const UsersController = require('../controllers/users.controller')
const AuthorizationMiddleware = require('../middlewares/authorization.middleware')
exports.routesConfig = (app) => {
app.post('/api/users',[
AuthorizationMiddleware.verifyValidJWT
], UsersController.insert)
}
这是我的中间件
const jwt = require('jsonwebtoken')
require('../config/env.config')
exports.verifyValidJWT = (req, res, next) => {
if (req.headers['access-token']) {
try {
let authorization = req.headers['access-token'].split(' ');
if (authorization[0] !== 'Bearer') {
return res.status(401).json({
ok: false,
err: "Unauthorized, Need a valid token"
});
} else {
console.log(authorization[1]);
req.jwt = jwt.verify(authorization[1], process.env.SEED_AUTH);
return next();
}
} catch (error) {
return res.status(403).json({
ok: false,
err: "Forbidden, need a valid token -> " + error.message
});
}
} else {
return res.status(401).json({
ok: false,
err: "Need to recieve a valid token"
});
}
}
最后是 API UsersController.insert
我试图用这个 api 做的是创建一个新用户。
为了更好地理解,这是我的 LOGIN API
const User = require('../models/users.model')
const { signUpValidation, logInValidation } = require('../middlewares/auth.validation.data')
const bcrypt = require('bcrypt')
const jwt = require('jsonwebtoken')
exports.logIn = async (req, res) => {
let body = req.body;
//Validation
const { error } = logInValidation(body)
if (error) {
return res.status(400).json({
ok: false,
err: error.details[0].message
})
}
//Check if the email already exists in the database
const user = await User.findOne({ email: body.email })
if (!user) {
return res.status(400).json({
ok: false,
err: "Invalid Email or password!"
})
}
const validPass = await bcrypt.compareSync(body.password, user.password)
if (!validPass) {
return res.status(400).json({
ok: false,
err: "Invalid Email or password!"
})
}
const token = jwt.sign(
{
_id: user._id,
email: user.email
},
process.env.SEED_AUTH,
{
expiresIn: process.env.TOKEN_EXPIRY
}
)
res.header('access-token', token).json({
ok: true,
user: {
id: user._id,
email: user.email
}
});
}
注册和登录验证 我使用这些中间件来验证它是否是有效的电子邮件,以及包含最少字母数的名称...
我的process.env.TOKEN_EXPIRY 设置为300(我明白,它以秒为单位),不过我尝试过更大的数字
(API 无需中间件即可工作)。
我没有看到的问题是什么。感谢您的帮助。
【问题讨论】:
-
您能否添加令牌生成代码(.sign())。另外建议使用 SSL 密钥对而不是明文密码
-
是的,我会添加它,在将用户存储到数据库之前,我已经使用 bcrypt 模块对密码进行了哈希处理
-
@Simon 问题不是用户密码,而是 jwt 密钥。有 2 种方法可以对令牌进行签名:使用预共享密钥 (PSK) 也就是您在此处拥有的秘密,或者您可以通过使用私钥签名并使用公钥进行验证来使用密钥对。这通常是首选方法。
-
您好,感谢您的回复,我不知道第二个我认为我会调查它,因为我已经不明白如何实现它了。那是我的错误吗?因为我已经用相同的模式完成了几个教程,它适用于他们。我已经用我的登录逻辑更新了问题,以便更好地理解
-
也许使用 iat 和 exp 字段而不是 expiresIn?
标签: node.js api authentication routes jwt