NodeJs - 从 JWT 令牌中检索用户信息?

Posted

技术标签:

【中文标题】NodeJs - 从 JWT 令牌中检索用户信息?【英文标题】:NodeJs - Retrieve user information from JWT token? 【发布时间】: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);

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

【问题讨论】:

【参考方案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 语句本身上失败了。甚至没有进入里面。

以上是关于NodeJs - 从 JWT 令牌中检索用户信息?的主要内容,如果未能解决你的问题,请参考以下文章

MSAL Angular:如何从 JWT 令牌中检索用户角色?

NodeJs Express passport-jwt 从令牌中获取错误的用户

如何从 JWT 标头中获取值到 nodejs 中的变量中?

使用 JWT Token、React Native 和 Redux 检索用户信息

如何从当前用户检索(Jwt)访问令牌并将其传递给 asp.net 样板(abp)中的移动应用程序?

如何使用passport-jwt在nodejs中发送/提取JWT令牌?