Можно ли динамически построить обратный вызов для facebook-pasport?

При использовании facebook-паспорта обычной задачей является указать redirect_uri в конструкторе FacebookStrategy, который вы используете, примерно так:

passport.use("facebook", new FacebookStrategy({
    //TODO: Correctly configure me
    clientID: "XXXXXXX"
  , clientSecret: "XXXXXXXXX"
  , callbackURL: "http://localhost:3007/auth/facebook/callback"
  },
  function(accessToken,refreshToken,profile,done) {
    User.findByFacebookId(profile.id, function(err,user) {
      if(err){ return done(err);}
      if(!user){ return done(null,false)}
      return done(null, user);
    });
  })
);

Затем вы должны настроить маршруты следующим образом:

app.get('/auth/facebook/login', passport.authenticate('facebook') );
app.get('/auth/facebook/login_callback', passport.authenticate('facebook', {
    successRedirect:"/login_ok.html"
  , failureRedirect:"/login_failed.html"
  }
))

Можно ли изменить URL-адрес обратного вызова, чтобы он содержал информацию из параметров, переданных на начальный логин?

ПРИМЕЧАНИЕ. Этот вопрос больше подходит для сохранения информации, которая занимала меня некоторое время, чтобы выработать, чтобы другие не сходили по тем же путям.

Ответ 1

Я нашел ответ, используя некоторую информацию, найденную здесь https://github.com/jaredhanson/passport-facebook/issues/2, и через то, как компонент oauth2 паспорта определяет обратный вызов uris, и информацию о пользовательских обратных вызовах паспорта в нижней части этой страницы http://passportjs.org/guide/authenticate/.

Вот пример, который отображает вызовы /auth/facebook/login/1234 для использования обратного вызова /auth/facebook/login_callback/1234

app.get('/auth/facebook/login/:id', function(req,res,next) {
  passport.authenticate(
    'facebook', 
     {callbackURL: '/auth/facebook/login_callback/'+req.params.id }
  )(req,res,next);
});

app.get('/auth/facebook/login_callback/:id', function(req,res,next) {
  passport.authenticate(
    'facebook',
     {
       callbackURL:"/auth/facebook/login_callback/"+req.params.id
     , successRedirect:"/login_ok.html"
     , failureRedirect:"/login_failed.html"
     }
   ) (req,res,next);
 });

Ответ 2

@OMGPOP, здесь вы можете передать параметры запроса в свой callbackUrl.

var Passport = require('passport');
var FacebookStrategy = require('passport-facebook').Strategy;
const Router = require("express").Router();
var fbConfig = {
  display: "popup",
  clientID: "YourFbClientId",
  clientSecret: "YourFbClientSecret",
  callbackURL: "http://localhost:8686/auth/facebook/callback",
  profileFields: ['id', 'name', 'gender', 'displayName', 'photos', 'profileUrl', 'email']
}

Passport.use(new FacebookStrategy(fbConfig,
  function(accessToken, refreshToken, profile, callback) {
    return callback(null, accessToken);
  }
));

Router.get("/auth/facebook", function(req, res, next) {
  var callbackURL = fbConfig.callbackURL + "?queryParams=" + req.query.queryParams;
  Passport.authenticate("facebook", { scope : ["email"], callbackURL: callbackURL })(req, res, next);
});

Router.get("/auth/facebook/callback", function(req, res, next) {
  Passport.authenticate("facebook", {
    callbackURL: fbConfig.callbackURL + "?queryParams=" + req.query.queryParams,
    failureRedirect: "/login",
    session: false
  })(req, res, next) },
  function(req, res) {
  console.log(req.query.queryParams);
  //do whatever you want
});

Зайдите в мой блог для получения дополнительной информации: http://blog.pingzhang.io/javascript/2016/09/22/passport-facebook/

Ответ 3

Я изо всех сил старался сделать это специально с Angularjs и хотел перенаправить обратно на тот же URL-адрес, с которого был инициирован вход.

Мое решение состояло в том, чтобы создать маршрут в Angularjs, который просто реализует местоположение назад. Я знаю, что это не отвечает конкретно на вопрос, но я думал, что это будет полезно для тех, кто хочет сделать то же самое.

На сервере:

app.get('/auth/facebook/', passport.authenticate ('facebook'));

app.get('/auth/facebook/callback', function (req, res, next) {
    var authenticator = passport.authenticate ('facebook', {
            successRedirect: '/fbcallback',
            failureRedirect: '/'
    });

    delete req.session.returnTo;
    authenticator (req, res, next);
})

Angular маршрутизатор:

when('/fbcallback', {
    template: "",
    controller: 'fbCtrl' 
}).

Angular:

app.controller("fbCtrl", function () {
    window.history.back();
});

Возможно, вы также можете выполнить некоторую другую маршрутизацию на стороне клиента в контроллере.