nodejs passport authentication token
Asked Answered
U

3

72

I am writing a nodejs application that I would like to use as both a web application, as well as an API provider. Once a user is authenticated, I want to assign that user a token to be used for subsequent requests. This works great with passport for the web application, as I just serialize and deserialize the user with the token in the session. However, when responding to API requests, there is no cookie to set to store the session information. Ideally, passport would look for the token both in session and the request body. Is there any way to configure passport to accomplish this?

Unalterable answered 1/7, 2013 at 3:27 Comment(0)
C
130

Simply use the access token on every request. Using a session is NOT needed. The following is the workflow:

POST /signin
  1. The username and password are posted in the client request.
  2. The server authenticates the user by using passport's Local Strategy. See passport-local.
  3. If the credentials represent a valid user, the server returns the access token generated by some generator. node-jwt-simple is a good choice.
  4. If the credentials are invalid, redirect to /signin.

When the client receives the access token from the authorization server, it can then make requests to protected resources on the server. For example:

GET /api/v1/somefunction?token='abcedf'

  1. The client calls some server api with the token argument.
  2. The server authenticates the token by using passport's Bearer Strategy. See passport-http-bearer.

References

Make a secure oauth API with passport.js and express.js (node.js)

Contemplative answered 15/8, 2013 at 3:5 Comment(7)
Thank you sooooo much for this. For some reason I thought OAuth needed to be more complicated than this.Alcyone
Regarding the token generation, is it secure to have one token that never expires? DO i have to make tokens expire and generate new ones?Bresnahan
@giamfreeg A token should expire after a certain period of time for security purposes.Mccarley
Great answer, but while not entirely related (and sorry for commenting two years later!), you should NOT pass the token in a GET parameter! There's a lot of potential places you could leak it and someone with bad intentions will get ahold of it.Nonresistance
You say to use node-jwt-simple which does encryption. But you skipped why you would need to encrypt the token, and how to validate the token. Are you supposed to store unencrypted tokens but pass encrypted tokens back to the client? Then when an encrypted token comes in, decrypt it, and verify the decrypted token lives in the database?Labourer
Thanks for this, i can't believe passport doesn't have this as its own strategy? Instead we have to use 2 strategies and have a "custom" implementation in the middle of creating tokens :(Salvatore
How do you send the token to the client? All I figured is that passport is always doing redirects? How do you persist tokens in the client? And how do you avoid that the server is logging tokens?Voltz
K
7

As bnuhero mentions you don't need sessions (although that approach has its merits too). Here's a boiler-plate project that I'm starting for this: https://github.com/roblevintennis/passport-api-tokens

Here's an alternative and easy to follow tut (but it DOES use sessions). Might be a nice cross-reference: http://scotch.io/tutorials/javascript/easy-node-authentication-setup-and-local

And one more reference related: http://mherman.org/blog/2013/11/11/user-authentication-with-passport-dot-js/

Kirakiran answered 14/12, 2013 at 17:46 Comment(0)
U
0

You can use isAuthenticated() method in passport in nodejs. On every route you can make a check if(req.isAuthenticated()) and if it is already authenticated it will allow you to access the route or you can redirect or perform any other any other execution in else block. In Passport you can return done(null, user) for successful login and it will store the data in the cookie until the session is ended. in user you can information about the user like email, password.

app.get('/home', (req, res) =>{
    if(req.isAuthenticated()){
        //render home page
    } else {
        // go back to the login page or throw soome error
    }
}) 
Underline answered 31/10, 2018 at 6:25 Comment(1)
This goes against the idea of using an Express Middleware like Passport. Not a clean or maintainable solution.Uncouple

© 2022 - 2024 — McMap. All rights reserved.