I've been using Passport on my server for user authentication. When a user is signing in locally (using a username and password), the server sends them a JWT which is stored in localstorage, and is sent back to server for every api call that requires user authentication.
Now I want to support Facebook and Google login as well. Since I began with Passport I thought it would be best to continue with Passport strategies, using passport-facebook and passport-google-oauth.
I'll refer to Facebook, but both strategies behave the same. They both require redirection to a server route ('/auth/facebook' and '/auth/facebook/callback' for that matter). The process is successful to the point of saving users including their facebook\google ids and tokens on the DB.
When the user is created on the server, a JWT is created (without any reliance on the token received from facebook\google).
... // Passport facebook startegy var newUser = new User(); newUser.facebook = {}; newUser.facebook.id = profile.id; newUser.facebook.token = token; // token received from facebook newUser.facebook.name = profile.displayName; newUser.save(function(err) { if (err) throw err; // if successful, return the new user newUser.jwtoken = newUser.generateJwt(); // JWT CREATION! return done(null, newUser); });
The problem is that after its creation, I don't find a proper way to send the JWT to the client, since I should also redirect to my app.
app.get('/auth/facebook/callback', passport.authenticate('facebook', { session: false, successRedirect : '/', failureRedirect : '/' }), (req, res) => { var token = req.user.jwtoken; res.json({token: token}); });
The code above redirects me to my app main page, but I don't get the token. If I remove the successRedirect, I do get the token, but I'm not redirected to my app.
Any solution for that? Is my approach wrong? Any suggestions will do.
A Passport strategy for authenticating with a JSON Web Token. This module lets you authenticate endpoints using a JSON web token. It is intended to be used to secure RESTful endpoints without sessions.
It provides an entry point: “/auth/facebook” that redirects to FBs and proceeds to the authentication. After that it acquires the AccessToken for the logged user and creates a JWT Token that returns to the client.
So to authenticate an API route using passport-facebook-token, you'll need to set up a passport strategy like so: passport. use('facebook-token', new FacebookTokenStrategy({ clientID : "123-your-app-id", clientSecret : "ssshhhhhhhhh" }, function(accessToken, refreshToken, profile, done) { // console.
JSON Web Token and Passport can be primarily classified as "User Management and Authentication" tools. JSON Web Token and Passport are both open source tools. It seems that Passport with 15.9K GitHub stars and 936 forks on GitHub has more adoption than JSON Web Token with 2.59K GitHub stars and 259 GitHub forks.
The best solution I found for that problem would be to redirect to the expected page with a cookie which holds the JWT.
Using res.json
would only send a json response and would not redirect. That's why the other suggested answer here would not solve the problem I encountered.
So my solution would be:
app.get('/auth/facebook/callback', passport.authenticate('facebook', { session: false, successRedirect : '/', failureRedirect : '/' }), (req, res) => { var token = req.user.jwtoken; res.cookie('auth', token); // Choose whatever name you'd like for that cookie, res.redirect('http://localhost:3000'); // OR whatever page you want to redirect to with that cookie });
After redirection, you can read the cookie safely and use that JWT as expected. (you can actually read the cookie on every page load, to check if a user is logged in)
As I mentioned before, it is possible to redirect with the JWT as a query param, but it's very unsafe. Using a cookie is safer, and there are still security solutions you can use to make it even safer, unlike a query param which is plainly unsecure.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With