首页 > 解决方案 > 验证 JWT 令牌的问题

问题描述

我有一个 express nodejs 后端,其中包含三个 URL 函数

1) registerUser() 将用户详细信息添加到数据库并为调用者提供 JWT

2) verifyToken() - 验证 JWT 是否有效

3) getConfiguration()- 如果 JWT 从上述函数中验证,则为用户提供一些配置数据

所以我用来实现这一点的快速代码是

//Routes.js

app.use(requestIp.mw())

app.route('/register')
    .post(userController.registerUser);

app.use(userController.verifyToken)

app.route('/user/configuration')
    .post(chayakkadaController.getConfiguration);

现在我的问题是,每当我尝试调用 URL /register 而不是调用 registerUser 函数时,它都会调用 verifyToken 并说我的令牌无效(我希望 registerUser 函数在没有令牌的情况下工作,但 getConfiguration 应该只与令牌一起工作)

这是我的 verifyToken 函数

export function verifyToken(req, res, next) {
var token = req.body.token || req.headers["token"];
var appData = {};
if (token) {
    jwt.verify(token, process.env.SECRET_KEY, function (err, decoded) {
        if (err) {
            appData["status"] = 1;
            appData["error"] = "Invalid Token";
            res.status(500).json(appData);
        } else {
            req.user = decoded;
            next();
        }
    });
} else {
    appData["status"] = 1;
    appData["error"] = "Need access token";
    res.status(403).json(appData);
}
}

我的注册用户代码

export function registerUser(req, res) {
let userData = {
    device: req.body.device,
    device_version: req.body.device_version,
    device_id: req.body.device_id,
    app_version: req.body.app_version,
    app_id: 2,
    ip_address: req.headers['x-real-ip'] || req.connection.remoteAddress
}
database.query(`INSERT INTO users SET ?`, userData)
    .then(result => {
        let user = {
            id: result.insertId
        }
        let token = jwt.sign(user, process.env.SECRET_KEY);
        let appData = {};
        appData["token"] = token;
        redis.sendMessage({
            qname: 'registration_queue',
            message: result.insertId + '',
        }, (err, resp) => {
            res.status(201).json(appData);
        });

    })
    .catch(err => {
        console.log(err);
        res.status(500).json("Database Error");
    })
}

标签: javascriptnode.jsexpressjwt

解决方案


为什么要发明轮子?有一个 NPM 模块: express-jwt

它具有检查 jwt 的中间件,如果它有效,它会解码有效负载并将其添加到请求中,然后继续到你的控制器,如果它无效,它会抛出一个错误,你应该抓住它,然后做任何事情你要。

它具有该unless功能,因此您可以将整个子路径配置为受限,除非它是/register

router.use(`admin/`, [
  expressJwt({ secret: jwtSecret }).unless({
    path: ['/register]
  }),
]);

推荐阅读