簡體   English   中英

NodeJs - 從 JWT 令牌中檢索用戶信息?

[英]NodeJs - Retrieve user infor from JWT token?

節點和角度。 我有一個 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);
}

我是否也必須將令牌作為參數傳遞以檢索用戶詳細信息? 還是將用戶詳細信息也保存在單獨的會話變量中?

首先,使用 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);
}

從請求數據中查找令牌:

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

您正在使用兩個回調調用函數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 方法返回一個 響應對象 確保你想要的不是$scope.myDetails = res.data

在您的 Users.js 文件中,您直接使用變量headers.authorization ,而它應該是req.header.authorization

var authorization = req.headers.authorization;

根據文檔https://github.com/themikenicholson/passport-jwt ,您可以使用request.user 請注意,我假設您使用的是帶有passport-jwt 的passport。 這是可能的,因為在身份驗證上下文中的通行證正在設置請求對象並填充用戶屬性。 因此,只需訪問該屬性。 你不需要做中間件。

Anderson anzileiro 是正確的。 如果您在中間件代碼中返回完整令牌,則該請求確實填充了用戶屬性,您可以訪問您的個人資料。

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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM