通过 Passport OAuth 流传递 URL 参数
Posted
技术标签:
【中文标题】通过 Passport OAuth 流传递 URL 参数【英文标题】:Passing through URL parameters through Passport OAuth flow 【发布时间】:2017-10-12 03:58:40 【问题描述】:我目前使用出色的 Passport 框架在 node.js 中实现了 Google OAuth2,但我发现在工作流中传递 URL 参数很困难。
例如,我想做一个像/analysis?id=1234
这样的网址,然后能够加载特定的分析。
一旦您已经通过身份验证并且会话尚未过期,它就可以工作,但是当您尚未通过身份验证时,它就不会工作。我正在努力将它传递给我认为的 callbackURL。任何指导将不胜感激!
这是我目前所拥有的(仅相关代码)
var session = require('express-session');
var storage = require('node-persist');
var passport = require('passport');
var GoogleStrategy = require('passport-google-oauth2').Strategy;
var GOOGLE_CLIENT_ID = "<google_client_id>"
, GOOGLE_CLIENT_SECRET = "<google_client_secret>",
GOOGLE_CALLBACKURL = "http://localhost:1425/auth/google/callback";
app.use(session(
maxAge: 86400000, // 24 hours
secret: 'no-one-will-find-out',
resave: true,
saveUninitialized: true
));
var sess;
app.use(passport.initialize());
app.use(passport.session());
storage.initSync();
passport.use(new GoogleStrategy(
clientID: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET,
callbackURL: GOOGLE_CALLBACKURL
,
function(accessToken, refreshToken, profile, cb)
return cb(null, profile);
));
passport.serializeUser( function(user, cb)
cb(null, user);
);
passport.deserializeUser( function(obj, cb)
cb(null, obj);
);
app.get('/login', function (req, res)
var id = req.query_id;
if (id)
var url = '/auth/google?id=' + id;
else
var url = '/auth/google';
res.render('landing', url: url, layout: 'landing.hbs');
);
app.get('/login_error', function (req, res)
var url = '/auth/google';
res.render('landing', url: url, error: 'show', layout: 'landing.hbs');
);
app.get('/analysis', ensureAuthenticated, function (req, res)
sess = req.session;
var email = res.req.user.email;
var domain = res.req.user._json.domain;
var img = res.req.user._json.image.url;
var id = req.query.id;
console.log(id);
sess.email = encodeURIComponent(email);
sess.domain = encodeURIComponent(domain);
if (domain == 'dropbox.com')
if (id)
res.render('index', email: email, img: img, query: id );
else
res.render('index', email: email, img: img, query: '' );
else
res.redirect('/login_error');
);
app.get('/auth/google', passport.authenticate('google', scope: [
'https://www.googleapis.com/auth/plus.login',
'https://www.googleapis.com/auth/plus.profile.emails.read']
));
app.get('/auth/google/callback',
passport.authenticate('google',
failureRedirect: '/login_error'
),
function(req, res)
var id = req.query.id;
// Successful authentication, redirect home.
if (id)
res.redirect('/analysis?id=' + id);
else
res.redirect('/analysis');
);
function ensureAuthenticated(req, res, next)
var id = req.query.id;
sess = req.session;
if (req.isAuthenticated())
return next();
else
console.log('need to login');
if (id)
res.redirect('/login?id=' + id);
else
res.redirect('/login');
【问题讨论】:
你能更好地解释一下你想做什么吗?你想传递什么参数? 稍微更新了一下——我基本上想加载一个依赖于提供的id的特定分析,例如/analysis?id=1234
。如果尚未通过身份验证,则需要初始化该 OAuth 流程,然后加载正确的分析。
【参考方案1】:
我不确定,但我相信 google auth 不会将您的“查询字符串”发回给您。
所以也许,你可以把你的 'id' 参数放在会话中:
在此处设置会话:
app.get('/auth/google', function(req, res, next)
req.session.analysis_id = req.query.id;
next();
, passport.authenticate('google', scope: [
'https://www.googleapis.com/auth/plus.login',
'https://www.googleapis.com/auth/plus.profile.emails.read']
));
在此处检索:
app.get('/auth/google/callback',
passport.authenticate('google',
failureRedirect: '/login_error'
),
function(req, res)
var id = req.session.analysis_id;
// Successful authentication, redirect home.
if (id)
res.redirect('/analysis?id=' + id);
else
res.redirect('/analysis');
);
你怎么看?
干杯!
【讨论】:
我没有在/auth/google/
路由中添加req.session.analysis_id = req.query.id;
,而是将它添加到了ensureAuthenticated 函数中,并且成功了!感谢您建议我使用会话!以上是关于通过 Passport OAuth 流传递 URL 参数的主要内容,如果未能解决你的问题,请参考以下文章
laravel 的passport Oauth 认证登录请求 的 oauth_token 重置
Passport (oAuth2) 如何与 GraphQL (TypeGraphQL) 一起使用?