NodeJs - Retrieve user information from JWT token?

59,681

Solution 1

First of all, it is a good practice to use Passport middleware for user authorization handling. It takes all the dirty job of parsing your request and also provides many authorization options. Now for your Node.js code. You need to verify and parse the passed token with jwt methods and then find the user by id extracted from the token:

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

Solution 2

Find a token from request data:

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

Solution 3

Your are calling the function UserService.me with two callbacks, although the function does not accept any arguments. What I think you want to do is:

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

Also, note that the $http methods return a response object. Make sure that what you want is not a $scope.myDetails = res.data

And in your Users.js file, you are using the variable headers.authorization directly, whereas it should be req.header.authorization:

var authorization = req.headers.authorization;
Share:
59,681

Related videos on Youtube

hakuna
Author by

hakuna

FullStack developer & DevSecOps engineer primarily works on Microsoft .Net,Angular2-5,AWS/Azure,HTML,CSS,SQL Server, Oracle, setting up infrastructure, configuration and deployment. Worked with various clients, business domains across multiple large/small scale projects leading/managing the teams with in US and internationally.

Updated on December 19, 2021

Comments

  • hakuna
    hakuna over 2 years

    Node and Angular. I have a MEAN stack authentication application where I am setting a JWT token on successful login as follows, and storing it in a session in the controller. Assigning the JWT token to config.headers through service interceptor:

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

    authservice.js Interceptor(omitted requestError,response and 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;
                }               
            };
        }]);
    

    Now I wanted to get the logged in user details from the token, How can I do that? I tried as follows, not working. When I log the error from Users.js file it's saying "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 (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);
    }
    

    Do i have to pass the token as a parameter too for retrieving the user details? Or save the user details in a separate session variable as well?

  • hakuna
    hakuna over 8 years
    Thanks for correcting my function, although this is a problem too my primary problem is not able to retrieve the token from config.headers. do you have any idea?
  • Pedro M. Silva
    Pedro M. Silva over 8 years
    Sorry, missed that error. See the answer now to check if it is fixed. :)
  • hakuna
    hakuna over 8 years
    Corrected it, still the issue persists. In fact it's failing at the if statement itself in users.js. not even entering inside.
  • hakuna
    hakuna over 8 years
    Thank you very much ! It worked. Just have to do a simple change decoded = jwt.verify(authorization.split(' ')[1],secret.secretToken); as i have Bearer + token as my token.
  • hakuna
    hakuna over 8 years
    I found more advantages for using JWT rather than using passport. I'm following these two : kdelemme.com/2014/03/09/… and code.tutsplus.com/tutorials/…. Please advice if passport is a good choice.
  • Constantine Poltyrev
    Constantine Poltyrev over 8 years
    Passport can use JWT just the same. It just provides you a convenient abstraction from the authentication procedures. My router code for protected methods looks like this: app.get('/api/content', passport.authenticate('local-authorization', { session: false }),api.listContent);
  • An-droid
    An-droid over 6 years
    I get 'jwt.verify is not a function' with your solution
  • Constantine Poltyrev
    Constantine Poltyrev over 6 years
    You should import the jwt library to make this code work. github.com/auth0/node-jsonwebtoken