简体   繁体   中英

Passport.JS - authorize with no session?

How to use authorization (binding to existing account) if no session is being used? I cannot find a way know which user wanted to authorize in the first place after authorization response comes back from facebook. With no session it is impossible to tell that... token is no longer present in the request (neither the user). Normally they would take that information from session. Tried continuation local storage but it won't work as passport makes several internal callbacks which I cannot bind to current context.

http://passportjs.org/docs/authorize

as you specified you are using Passport.JS with Facebook strategy, you can use the state field. you will need to create 2 middlewares, one to be used before you call the authenticate for the login URI, and another to be used before the loginCallback URI.

Keep in mind that you will need to also update your strategy to manage the users properly. remember, you cannot use 'req.user,

I personally dont like the sessions too, but its very common to find info about how to use auth with them.

Please check how this method is calling the 'authenticate'passport method disabling the session and is also in a middleware fashion, you can of course do this in-line with you router.get(...) but I found it a good practice as in my app I use local, facebook and JWT auth simultaneously and I like to have a consistent pattern. Also, if you plan to create and save the token. you may run into troubles handling the callback if you happen to use asynchronous storage, like mongoDB.

According to the documentation you should use authorize if you will use that endopoint to connect to a local account, but as you wont have sessions at all, it makes no sense to use, never the less I think you should have 2 paths, one for registering with facebook, and another if you plan to merge a local account with facebook, in wich case the token passed to facebook can determine if its first time or connect)

Do not forget to disable the session in both authenticate calls.

function facebookTempTokenCreate(req, res, next) {
// create the token the way you think is best, 
// I personally prefer to create a JWT and save it somewhere in the DB.
// also you need to pass it to the next middleware by saving the value 
// in the req. name can be anything you want. 
// but make sure is quite unique as you do not want to break other libraries.

   req.facebookConnectToken = 'that_sweet_token';
   next(); // dont forget to continue to next middleware.
}

function facebookAuthenticate(req, res, next) {        
    passport.authenticate('facebook', { 
        scope : 'email',
        callbackURL : 'your_app_callback_uri',
        state : req.facebookConnectToken,
        session : false
    })(req,res,next);
}

function facebookAuthenticateCallback(req, res, next) {

    passport.authenticate('facebook', { 
        scope : 'email',
        session : false
    })(req,res,next);
}

function facebookTempTokenValidate(req, res, next) {    
    console.log('here we validate the token: ' + req.query.state );
    next();//dont forget to pass execution to next middleware.
}

app.get('/facebook/login', facebookTempTokenCreate, facebookAuthenticate);

app.get('/facebook/login/callback', facebookTempTokenValidate, facebookAuthenticateCallback);

You can find further info in this link. https://github.com/jaredhanson/passport-facebook/issues/14

Hope this can help you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM