NodeJs - Извлечение информации пользователя из токена JWT?

Node и Angular. У меня есть приложение проверки подлинности стека 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: заголовки не определены"

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(Node):

 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 для обработки авторизации пользователей. Он берет на себя всю грязную работу по разбору вашего запроса, а также предоставляет множество вариантов авторизации. Теперь для вашего кода Node.js. Вам необходимо проверить и проанализировать переданный токен с помощью методов jwt, а затем найти пользователя по идентификатору, извлеченному из токена:

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);
}

Ответ 2

Найти токен по данным запроса:

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

Ответ 3

Вы вызываете функцию 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;

Ответ 4

Согласно документации https://github.com/themikenicholson/passport-jwt, вы можете использовать request.user. Обратите внимание, я предполагаю, что вы используете паспорт с passport-jwt. Это возможно, потому что паспорт в контексте аутентификации устанавливает объект запроса и заполняет свойство пользователя. Итак, просто получите доступ к этой собственности. Вам не нужно делать промежуточное программное обеспечение.