2012-03-27 3 views
17

Я использую экспресс-и паспортную политику OpenID Google, и я хотел бы установить returnURL для каждого запроса auth, чтобы иметь возможность вернуться на страницу, инициировавшую этот auth.Пользовательский returnUrl на Node.js Стратегия Google Passport

Ситуация в том, что у меня есть приложение для слайдов HTML5 с бэкэндом Node.js (и с социальным материалом и редактором, а также с порталом и расширениями ... https://github.com/bubersson/humla), и я хочу иметь возможность входа пользователя на какой-либо слайд (через меню слайдов ...), но затем я хочу, чтобы он легко вернулся к тому же слайду.

Значит, мне нужно что-то вроде этого?

app.get('/auth/google', function(req,res) { 
    var cust = "http://localhost:1338/"+req.params.xxx; 
    passport.authenticate('google', returnURL:cust, function ... 
} 

Я ознакомился с паспортом, но до сих пор не знаю, как это сделать. Я знаю, что это будет небезопасно, но как еще я могу это сделать?

Или как я могу заставить приложение вернуться на страницу, с которой был начат вход? Или есть способ сделать аутентификацию OpenID с использованием AJAX (и все еще иметь возможность использовать паспорт)?

ответ

24

Я понял это для моих приложений аутентификации Twitter, я уверен, что GoogleStrategy очень похож. Попробуйте вариант этого:

Предполагая, что вы определили маршрут для обратного вызова от службы аутентификации, как так (из паспорта гида):

app.get('/auth/twitter/callback', 
    passport.authenticate('twitter', { 
     successRedirect: authenticationRedirect(req, '/account') 
    , failureRedirect: '/' 
    }) 
); 

Просто изменить этот блок к этому:

app.get('/auth/twitter/callback', function(req, res, next){ 
    passport.authenticate('twitter', function(err, user, info){ 
    // This is the default destination upon successful login. 
    var redirectUrl = '/account'; 

    if (err) { return next(err); } 
    if (!user) { return res.redirect('/'); } 

    // If we have previously stored a redirectUrl, use that, 
    // otherwise, use the default. 
    if (req.session.redirectUrl) { 
     redirectUrl = req.session.redirectUrl; 
     req.session.redirectUrl = null; 
    } 
    req.logIn(user, function(err){ 
     if (err) { return next(err); } 
    }); 
    res.redirect(redirectUrl); 
    })(req, res, next); 
}); 

Теперь определите промежуточное программное обеспечение для аутентифицированных маршрутов, чтобы сохранить оригинальный URL в сессии, как это:

ensureAuthenticated = function (req, res, next) { 
    if (req.isAuthenticated()) { return next(); } 

    // If the user is not authenticated, then we will start the authentication 
    // process. Before we do, let's store this originally requested URL in the 
    // session so we know where to return the user later. 

    req.session.redirectUrl = req.url; 

    // Resume normal authentication... 

    logger.info('User is not authenticated.'); 
    req.flash("warn", "You must be logged-in to do that."); 
    res.redirect('/'); 
} 

Работает!

+0

Это работает отлично, но при перенаправлении, кажется, отсутствуют параметры хеширования, если пользователь отправлен для аутентификации и возвращается. Может ли быть способ сохранить их в URL-адресе при перенаправлении после входа в систему? http://stackoverflow.com/questions/14124932/passport-js-express-js-forward-user-to-original-destination-after-authenticati – prototype

+0

@ user645715 может попытаться использовать 'req.session.redirectUrl = req.originalUrl ; вместо или 'req.url' –

+0

работает как шарм, спасибо :) – Zub

5

Попробуйте res.redirect('back'); в функции обратного вызова для passport.authenticate

+0

Ha спасибо! По-видимому, обратный маршрут устанавливается между первым и вторым запросами OpenID. Я этого не знал! Спасибо – bubersson

+2

Ну, я нашел проблему с этим. Он работает только в том случае, если я уже зарегистрирован в Google. Если паспорт перенаправляется на страницу Google, а затем возвращается на мой сайт - маршрут «страница» теряется. Есть ли другой способ заставить его вернуться из Google в мое местоположение (страница, с которой был начат вход в систему)? – bubersson

+0

@ bubersson вам нужно будет использовать более проактивный подход, такой как тот, на первом ответе, для этого, если я правильно понимаю. – matanster

3

По мнению автора, это невозможно с помощью стратегий OpenID. Нам удалось обновить эти динамически прямой доступ к переменным:

app.get('/auth/google', function(req, res, next) { 
    passport._strategies['google']._relyingParty.returnUrl = 'http://localhost:3000/test'; 
    passport._strategies['google']._relyingParty.realm = 'http://localhost:3000'; 
    passport.authenticate('google')(req, res, next); 
}); 
13

Везде, где у вас есть кнопка входа в системе, приобщать текущий URL в запросе в качестве параметра запроса (настроить для любого шаблонизатора вы используете):

<a href='/auth/google?redirect=<%= req.url %>'>Log In</a> 

Затем добавьте промежуточное программное обеспечение для вашего GET /auth/google обработчика, который хранит это значение в req.session:

app.get('/auth/google', function(req, res, next) { 
    req.session.redirect = req.query.redirect; 
    next(); 
}, passport.authenticate('google')); 

Наконец, в обработчике обратного вызова перенаправляйте URL-адрес, хранящийся в сеансе:

app.get('/auth/google/callback', passport.authenticate('google', 
    failureRedirect: '/' 
), function (req, res) { 
    res.redirect(req.session.redirect || '/'); 
    delete req.session.redirect; 
}); 
+0

Можно ли сделать это без сеансов? – nahtnam

Смежные вопросы