5

I've been working with Sails since couple of weeks ago, I came from Rails and I don't have any experience working with Node.js.

Now I'm trying to make a robust token authentication using jsonwebtoken. https://github.com/auth0/node-jsonwebtoken

I followed this guide http://thesabbir.com/how-to-use-json-web-token-authentication-with-sails-js/ and everything worked fine. I'm able to make a sign up, sign in and then use the token correctly for different actions.

Now, there are some actions where I'd like to use the login user, something like devise current_user helper. For example, when creating a comment, this comment should belongs to the current user.

Using Sabbir Ahmed guide, in the line 33 from the isAuthorized.js policy the token gets decrypted so I can get the current user id from there.

So, my question is, what should be the best way to get the current user and be able to use it later in some controller? For example I tried something like:

# isAuthorized.js line 34, after getting decrypted token
User.findOne({id: token.id}).exec(function findOneCB(err, found){
    currentUser = found;
});

But, on this way, because this is an async action I can't use this currentUser in a controller.

I want to store the current user in order to be able to use it later in some controller without repeated the same code in each controller, something like a helper or maybe a service.

2 Answers2

4

The trick is where you place the next(). Since you are making an async call, the control should only be transferred to next policy/ controller once the database action is competed.

You should modify the policy to:

User.findOne({id: token.id}).exec(function findOneCB(err, found){
    if(err) next(err);
    req.currentUser = found;
    next();
});

And you should be able to access the user details in controllers that use isAuthorized policy via req.currentUser

MjZac
  • 3,476
  • 1
  • 17
  • 28
0

If by

For example, when creating a comment, this comment should belongs to the current user.

what you mean is certain attributes like username, and country etc, rather than querying the database after verification, what you can choose to do is to send these additional attributes to jwToken.issue in api/controllers/UsersController.js

eg.

jwToken.issue({ 
    id: user.id,
    username: user.name,
    country: user.country
    })

How that helps is, you can keep api/policies/isAuthorized.js as is, and in all the controllers that you use in the future, you can access the payload values from as

token.username or token.country

Instead of having to query the database again, thereby saving you valuable response time.

Beware however, of the data you choose to send in the token (you could also send {user:user} if you want to) however, as the secret key or hashing is not required to decrypt the payload as you can figure @ jwt.io , you might want to exercise restraint.

Paulo
  • 325
  • 3
  • 16