What's the best way to mix passport-facebook and passport-jwt?
Asked Answered
F

3

11

I am kind of new to Node.js development and currently working on a pet project on my free time.

So far I have created JWT authentication using passport and passport-jwt for the strategy and I am using it in all of my RESTful APIs.

Now I am thinking of mixing this with some sort of Facebook authentication still want to stick with token authentication.

Currently this is how I am generating and obtaining the token:

exports.authenticate = function(req, res) {
    User.findOne({
        email: req.body.email
    }, function(err, user) {
        if (err)
            return res.status(400).send(getErrorMessage(err));

        if (!user) {
            res.status(400).send({
                success: false,
                message: 'Authentication failed. User not found.'
            });
        } else {
            if (user.checkPassword(req.body.password)) {

                let token = jwt.encode(user, config.secretPhrase);

                res.json({
                    success: true,
                    token: 'JWT ' + token
                });
            } else {
                res.status(401).send({
                    success: false,
                    message: 'Authentication failed. Wrong password.'
                });
            }
        }
    });
};

app.route('/api/users/authenticate')
        .post(user.authenticate);

And to validate I do the following:

let user = require('../../app/controllers/user-controller');
app.route('/api/todos')
        .get(user.validateLogin, todos.list)
        .post(user.validateLogin, todos.create);

user-controller:

exports.validateLogin = passport.authenticate('jwt', {
    session: false
});

Anyone can suggest a neat way to mix the two strategies ? should I use express-jwt ? What's the difference between express-jwt and passport-jwt ?

Franconia answered 21/4, 2016 at 14:51 Comment(0)
K
2

you can use passport-facebook like what you did with passport-jwt with new strategy so you can save Facebook user token in your database and return your token

Kumasi answered 20/12, 2017 at 9:43 Comment(1)
This is the most common approach. You can implement multiple passport strategies for auth, and return your jwt on success. Would be a new auth route, if user has an account already and logs in w/ fb, look for the email in DB, if it exists then send your user the jwt.Dachau
M
0

It looks as if currently you're sending back the token to the end user. How are you saving that client side? I'd recommend using a simple JWT library like jsonwebtoken, and setting the token as an httpOnly cookie. If you're currently saving it in localStorage you might be more vulnerable to an XSS attack. Here is a gist with how I am currently handling setting and checking a JWT for a user: https://gist.github.com/briancw/8c2021817c3bd34972e8e8deb6048a4f

Mcfall answered 20/12, 2017 at 9:16 Comment(0)
F
0

You can first use the passport-jwt auth strategy, then inside the passport-facebook strategy pass to super() the argument passReqToCallback: true and add request as first parameter of your validate function, inside that function you can now combine the facebook oauth response and the req.user coming from your the passport-jwt strategy.

import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Profile, Strategy } from 'passport-facebook';
import { PrismaService } from 'src/commons/services/prisma.service';
import { Request } from 'express';

@Injectable()
export class FacebookStrategy extends PassportStrategy(Strategy, 'facebook') {
  constructor() {
    super({
      // ...
      passReqToCallback: true,
    });
  }

  async validate(
    req: Request, // add this param
    accessToken: string,
    refreshToken: string,
    profile: Profile,
    done: (err: any, user: any, info?: any) => void,
  ): Promise<any> {
    const payload = {
      profile,
      accessToken,
      user: req.user, //combine strategies here
    };

    done(null, payload); // payload will be available as req.user
  }
}
Favors answered 16/11, 2023 at 21:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.