【问题标题】:NodeJs - Retrieve user information from JWT token?NodeJs - 从 JWT 令牌中检索用户信息?
【发布时间】:2016-01-31 18:47:08
【问题描述】:

节点和角度。我有一个 MEAN 堆栈身份验证应用程序,我在成功登录时设置 JWT 令牌,如下所示,并将其存储在控制器的会话中。通过服务拦截器将 JWT 令牌分配给 config.headers:

var token = jwt.sign({id: user._id}, secret.secretToken, { expiresIn: tokenManager.TOKEN_EXPIRATION_SEC });
            return res.json({token:token});

authservice.js 拦截器(省略 requestError、response 和 responseError):

authServices.factory('TokenInterceptor', ['$q', '$window', '$location','AuthenticationService',function ($q, $window, $location, AuthenticationService) {
        return {
            request: function (config) {
                config.headers = config.headers || {};
                if ($window.sessionStorage.token) {
                    config.headers.Authorization = 'Bearer ' + $window.sessionStorage.token;
                }
                return config;
            }               
        };
    }]);

现在我想从令牌中获取登录用户的详细信息,我该怎么做?我尝试如下,不工作。当我从 Users.js 文件中记录错误时,它显示“ReferenceError: headers is not defined”

authController.js:

$scope.me = function() {
    UserService.me(function(res) {
      $scope.myDetails = res;
    }, function() {
      console.log('Failed to fetch details');
      $rootScope.error = 'Failed to fetch details';
    })
  };

authService.js:

authServices.factory('UserService',['$http', function($http) {
  return {        
    me:function() {
    return $http.get(options.api.base_url + '/me');
    }
  }
}]);

Users.js(节点):

 exports.me = function(req,res){
    if (req.headers && req.headers.authorization) {
        var authorization =req.headers.authorization;
        var part = authorization.split(' ');
        //logic here to retrieve the user from database
    }
    return res.send(200);
}

我是否也必须将令牌作为参数传递以检索用户详细信息?还是将用户详细信息也保存在单独的会话变量中?

【问题讨论】:

    标签: javascript angularjs node.js jwt


    【解决方案1】:

    安德森·安齐莱罗是正确的。如果您在中间件代码中返回完整的令牌,则该请求确实填充了用户属性,您可以访问您的个人资料。

    passport.use(
      new JWTstrategy(
        {
          secretOrKey: process.env.ACCESS_TOKEN_SECRET,
          // jwtFromRequest: ExtractJWT.fromUrlQueryParameter('secret_token')
          jwtFromRequest: ExtractJWT.fromAuthHeaderAsBearerToken()
        },
        async (token, done) => {
          try {
            return done(null, token);
          } catch (error) {
            done(error);
          }
        }
      )
    );
    

    req.user 将返回:

    {
        "user": {
            "username": "admin"
        },
        "iat": 1625920948,
        "exp": 1626007348
    }
    

    【讨论】:

      【解决方案2】:

      首先,使用 Passport 中间件进行用户授权处理是一个很好的做法。它承担了解析请求的所有繁琐工作,还提供了许多授权选项。 现在为您的 Node.js 代码。 您需要使用 jwt 方法验证和解析传递的令牌,然后通过从令牌中提取的 id 找到用户:

      exports.me = function(req,res){
          if (req.headers && req.headers.authorization) {
              var authorization = req.headers.authorization.split(' ')[1],
                  decoded;
              try {
                  decoded = jwt.verify(authorization, secret.secretToken);
              } catch (e) {
                  return res.status(401).send('unauthorized');
              }
              var userId = decoded.id;
              // Fetch the user by id 
              User.findOne({_id: userId}).then(function(user){
                  // Do something with the user
                  return res.send(200);
              });
          }
          return res.send(500);
      }
      

      【讨论】:

      • 非常感谢!有效。只需要做一个简单的改变 decoded = jwt.verify(authorization.split(' ')[1],secret.secretToken);因为我有 Bearer + token 作为我的令牌。
      • 我发现使用 JWT 比使用护照更有优势。我关注这两个:kdelemme.com/2014/03/09/…code.tutsplus.com/tutorials/…。请告知护照是否是一个不错的选择。
      • Passport 可以同样使用 JWT。它只是为您提供身份验证过程的方便抽象。我的受保护方法的路由器代码如下所示:app.get('/api/content', passport.authenticate('local-authorization', { session: false }),api.listContent);
      • 我得到'jwt.verify is not a function' 与您的解决方案
      • 您应该导入 jwt 库以使此代码正常工作。 github.com/auth0/node-jsonwebtoken
      【解决方案3】:

      从请求数据中查找令牌:

      const usertoken = req.headers.authorization;
      const token = usertoken.split(' ');
      const decoded = jwt.verify(token[1], 'secret-key');
      console.log(decoded);
      

      【讨论】:

        【解决方案4】:

        根据文档https://github.com/themikenicholson/passport-jwt,您可以使用request.user。请注意,我假设您正在使用带 passport-jwt 的护照。 这是可能的,因为身份验证上下文期间的护照正在设置请求对象并填充用户属性。所以,只需访问该属性。你不需要做中间件。

        【讨论】:

          【解决方案5】:

          您正在使用两个回调调用函数UserService.me,尽管该函数不接受任何参数。我认为你想做的是:

          $scope.me = function() {
              UserService.me().then(function(res) {
                $scope.myDetails = res;
              }, function() {
                console.log('Failed to fetch details');
                $rootScope.error = 'Failed to fetch details';
              });
            };
          

          另外,请注意 $http 方法返回 response object。确保你想要的不是$scope.myDetails = res.data

          在您的 Users.js 文件中,您直接使用变量 headers.authorization,而它应该是 req.header.authorization

          var authorization = req.headers.authorization;
          

          【讨论】:

          • 感谢您更正我的功能,尽管这也是一个问题,但我的主要问题是无法从 config.headers 检索令牌。你有什么想法吗?
          • 抱歉,错过了那个错误。现在查看答案以检查它是否已修复。 :)
          • 已更正,问题依旧。事实上,它在 users.js 中的 if 语句本身上失败了。甚至没有进入里面。
          猜你喜欢
          • 1970-01-01
          • 2018-03-17
          • 1970-01-01
          • 1970-01-01
          • 2015-04-28
          • 2019-05-23
          • 2016-08-07
          • 2021-10-22
          • 2020-01-03
          相关资源
          最近更新 更多