Skip to content

Instantly share code, notes, and snippets.

@cgiacomi
Last active February 20, 2018 05:05
Show Gist options
  • Save cgiacomi/cd1efa187b8cccbe2a61 to your computer and use it in GitHub Desktop.
Save cgiacomi/cd1efa187b8cccbe2a61 to your computer and use it in GitHub Desktop.
BearerStrategy using a JWT token
/*
* Bearer strategy for token authentication when accessing API endpoints
*/
passport.use(new BearerStrategy(
function(token, done){
try {
//we attempt to decode the token the user sends with his requests
var decoded = jwt.decode(token, tokenSecret);
//TODO: must check the token expiry and ensure the token is still valid
//if token is expired return 401! (throw an exception, will be caught by catch clause)
//we find the user that has made the request
User.findOne({ email: decoded.sub }, function (err, user) {
if (err) { return done(err); }
if (!user) {
return done(null, false); //no such user
}
else {
return done(null, user); //allows the call chain to continue to the intented route
}
});
}
catch(err){
return done(null, false); //returns a 401 to the caller
}
}
));
@cgiacomi
Copy link
Author

cgiacomi commented May 5, 2014

To ensure you use the bearer strategy in your routes do something like this:

Using express.js

app.get('/api/v1/resource', passport.authenticate('bearer', { session: false }), function(req, res, next){
  var user = req.user;

  //route implementation here...
});

And you since you are using Passport.js you would call the route something like this:

GET /api/v1/resource/?access_token=[JWT-TOKEN]

@wethinkagile
Copy link

Hi thanks for the examples. May I ask how you protect the routes on the API-side as the Client side can always be forged.

@cgiacomi
Copy link
Author

cgiacomi commented Oct 1, 2014

The way I do it is by storing a timestamp in the JWT token. When the client makes a request is passes the token along with the call, the REST backend will decode the token and check if the timestamp has elapsed, the timeout depends on what you think is a correct timeout (from a few hours to a few days).

Also in the JWT token you can store any other type of data you want to minimize the possibility of calls being forged.

On a personal note.... when dealing with destructive calls (for example, changes to the user profile, or deletion of sensitive data) I force the client to login again, and in the case of email changes I force the user to confirm the new email, while ensuring the user can also roll back from the old one. Of course everything goes over HTTPS.

Hope this helps :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment