【问题标题】:express-jwt authentication issue with web apiweb api 的 express-jwt 身份验证问题
【发布时间】:2018-08-20 21:57:04
【问题描述】:

我有一个应用程序正在使用下面显示的标准 jwt 身份验证,并从 express-jwt 自述文件中复制。

app.use(jwt({
  secret: 'hello world !',
  credentialsRequired: false,
  getToken: function fromHeaderOrQuerystring (req) {
    if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
        return req.headers.authorization.split(' ')[1];
    } else if (req.query && req.query.token) {
      return req.query.token;
    }
    return null;
  }
}));

当我点击 api 时,授权标头等于“Bearer hello world!”。这等于我的秘密,但我得到了未经授权的 401 抛出。有谁知道为什么? req.headers.authorization.split(' ')[1] 不应该等于秘密吗?

【问题讨论】:

    标签: node.js express jwt


    【解决方案1】:

    不,承载者不是你的秘密。它是一个 base64 编码的 jwt,包含(标头、有效负载和签名)。该密钥用于使用 jwt 标头中指定的算法对 jwt 有效负载进行签名。

    阅读official JWT website上的介绍以了解这个概念。

    【讨论】:

      【解决方案2】:

      您可以使用JsonWebtoken npm 包在您的 express 应用中实现基于 jwt 的身份验证。 这就是身份验证的工作原理:

      • 从包中导入 jwt

        const jwt = require('jsonwebtoken');

      在 login.service.js 文件或任何需要的地方设置令牌,并使用适当的数据作为有效负载:

       const token = jwt.sign('payload', 'secret key',
                     { expiresIn: 60*60 });
         how token looks: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYW5pcyIsImVtYWlsIjoic29tZW1lYWlsLmNvbSIsImlhdCI6MTUxNjIzOTAyMn0.FyDrUNkvDi82lYv8JioAB9Ih8vyn6Y6mY8PpUiIz8nY 
      

      您可以通过将令牌粘贴到jwt.io 网站上来对其进行解码。

      • 通常我们将令牌存储在 cookie 中(在 login.router.js 文件中发送响应之前将 cookie 设置为令牌):

         router.get('/auth/google/callback', (req, res, next) => {
          loginCtrl.redirectGoogle(req, res, next).then((result) => {
             res.cookie('userToken', token);
            res.redirect('/#/app/home');
             }, (err) => { 
             console.log("Error in authentication **[ ", err, " ]** ");
          res.redirect(500, '/#/login');
        });  
        
      • 现在编写一个在每个 API 请求(authentication.router.js 文件)之前调用的中间件(身份验证)。

      router.use((req, res, next) => {
        try {
          const token = req.cookies.currentUser;
             // console.log('cookie', token);
             // to  decode token
          if (token) {
            authCtrl.verifyToken(token, (err, decoded) => {
              if (err) {
                res.clearCookie(config.UserToken);
                res.status(401).json({ error: ' Session Timeout... Please login again' });
               // console.log('token expired');
      
               // res.redirect('/#/login');
              } else {
                req.user = decoded;
                next();
              }
                     // console.log('Token verified');
                     // res.cookie(config.cookie.name,successResult.authToken);
            });
          } else {
                 // if there is no token
                 // return an error
            return res.status(403).send({
              message: 'User not authenticated.',
            });
          }
        } catch (error) {
         // console.log(error);
          return error;
        }
      });
      • 在 auth.controller.js 文件中的 verifyToken 函数中,我们 解码令牌:

      const jwt = require('jsonwebtoken');
      
      const verifyToken = (usertoken, done) => {
        jwt.verify(usertoken,'secret key', (err, res) => {
          if (err) {
            return done(err);
          }
          return done(null, res);
        });
      };
      
      module.exports = {
        verifyToken,
      };

      现在您的 API 端点受到身份验证的保护。确保身份验证中间件位于 app.js 文件的顶部。

      router.use('/login', require('./modules/login'));
      router.use('/logout', (req, res) => {
        res.clearCookie(userToken);
        res.redirect('/');
      });
      router.use(require('./modules/authentication'));
      // Each Module to be placed after this
      router.use('/communityMembers',require('./modules/communitymember'));

      【讨论】:

        猜你喜欢
        • 2018-02-06
        • 2017-07-30
        • 2017-03-09
        • 2018-05-01
        • 2021-02-11
        • 1970-01-01
        相关资源
        最近更新 更多