【问题标题】:JWT expired, unexpected response in nodejs APIJWT 过期,nodejs API 中的意外响应
【发布时间】:2020-12-08 21:55:17
【问题描述】:

当我尝试在我的 node.js 服务器中使用私有 api 时遇到问题,这是我正在关注的过程

  1. 注册(如果用户没有帐户)或登录(已有帐户)。
  2. 它生成令牌并将它传递到标题res.header('access_token': token)
  3. 我复制此令牌并将其粘贴到我的私有 api 的标题部分(我现在使用邮递员对其进行测试),以验证用户是否已登录。
  4. 在我的路由中,我使用中间件将其私有化,验证用户是否可以使用资源 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


【解决方案1】:

process.env 变量是字符串而不是数字。根据jsonwebtoken 文档,字符串默认以毫秒为单位,数字默认以秒为单位。所以将 TOKEN_EXPIRY 从 300 改为 300000

【讨论】:

  • 感谢您的评论,这真的很有帮助。我使用环境变量TOKEN_EXPIRY 作为字符串。我将时间更改为 300000,它工作正常。感谢您的帮助,我正在实施错误的 TOKEN_EXPIRY
猜你喜欢
  • 2019-11-12
  • 1970-01-01
  • 2020-10-29
  • 1970-01-01
  • 2021-10-03
  • 1970-01-01
  • 2020-04-04
  • 2018-12-10
  • 1970-01-01
相关资源
最近更新 更多