使用 Everyauth/Passport.js 向 Twitter 进行身份验证,同时询问用户名/电子邮件/密码
Posted
技术标签:
【中文标题】使用 Everyauth/Passport.js 向 Twitter 进行身份验证,同时询问用户名/电子邮件/密码【英文标题】:Using Everyauth/Passport.js to authenticate with Twitter whilst asking for username/email/password 【发布时间】:2013-01-29 15:57:06 【问题描述】:我想创建一个身份验证系统,用户可以通过它“使用 Twitter 注册”,但这有效地完成了验证他们的 Twitter 帐户并使用他们的 Twitter 用户名预先填写注册表单。然后将要求用户输入电子邮件和密码(或备用用户名)。
因此,在注册后,用户已通过身份验证访问其 Twitter 帐户,并且访问令牌可以存储在数据库中。稍后我将使用它来访问 Twitter API。
everyauth
和 passport
等节点模块使用 OAuth 完成了很多繁重的工作,但它们似乎只提供了一个 findOrCreateUser
方法,它并没有提供很多喘息空间来做类似的事情我需要做的——即在注册用户之前重定向到注册表单,或者如果找到用户,则照常登录。
【问题讨论】:
【参考方案1】:这里是一个可能的方法的快速草图:
请注意,Passport 不提供findOrCreateUser
方法。所有数据库管理和记录创建都由您的应用程序定义(应该如此),Passport 只是提供身份验证工具。
这种方法的关键是从 twitter 提供的个人资料数据中简单地在您的数据库中创建一个“不完整”的用户记录。然后,在您的应用程序的路由中,您可以检查是否满足您需要的条件。如果没有,将用户重定向到一个表单,提示他们填写缺失的详细信息。
passport.use(new TwitterStrategy(
consumerKey: TWITTER_CONSUMER_KEY,
consumerSecret: TWITTER_CONSUMER_SECRET,
callbackURL: "http://127.0.0.1:3000/auth/twitter/callback"
,
function(token, tokenSecret, profile, done)
// Create a user object in your database, using the profile data given by
// Twitter. It may not yet be a "complete" profile, but that will be handled
// later.
return done(null, user);
));
app.get('/auth/twitter',
passport.authenticate('twitter'));
app.get('/auth/twitter/callback',
passport.authenticate('twitter', failureRedirect: '/login' ),
function(req, res)
// The user has authenticated with Twitter. Now check to see if the profile
// is "complete". If not, send them down a flow to fill out more details.
if (req.user.isCompleteProfile())
res.redirect('/home');
else
res.redirect('/complete-profile');
);
app.get('/complete-profile', function(req, res)
res.render('profile-form', user: req.user );
);
app.post('/update-profile', function(req, res)
// Grab the missing information from the form and update the profile.
res.redirect('/home');
);
【讨论】:
先生,这太棒了。非常感谢! 如果我想将 Twitter 个人资料数据传递到我检查个人资料是否已完成的地方怎么办?我需要这样做以便将数据存储在会话中,然后使用这些详细信息预先填写注册表。 我遇到的另一个问题是 Passport 将用户视为已通过身份验证,即使他们尚未完成个人资料。我已经设法通过编写检查身份验证和完整配置文件的中间件来解决这个问题。 如果我能以这种方式将数据传递给下一个函数就好了:done(null, new User( 'twitter.id': profile.id ), profile)
。 Passport 似乎允许第三个参数,但前提是第二个参数是错误的?
调用return done(null, user, profile)
,然后req.authInfo
将设置第三个参数(本例中的配置文件)。您使用中间件检查完整配置文件的方法是正确的。从用户证明其身份的意义上说,身份验证已完成。任何进一步的限制都是您的应用程序的限制,而不是严格的身份验证,因此它们应该由单独的中间件处理。【参考方案2】:
稍微澄清一下。测试“if (req.user.isCompleteProfile())”可能是:
如果(req.user.isCompleteProfile)
即,您在 twitter 步骤中创建用户记录时创建一个字段“isCompleteProfile”,并将其标记为真或假,具体取决于您对用户的了解
或者:它是对函数的调用,因此
if (isCompleteProfile(req))
在这种情况下,您有一个单独的函数来测试您刚刚创建/修改的用户的状态,因此:
function isCompleteProfile(req) if (typeof req.user.local.email === "undefined") 返回 false; 否则返回真;
而且,我对 Jared 和这个关于passportjs 身份验证的精彩教程表示赞同。
【讨论】:
以上是关于使用 Everyauth/Passport.js 向 Twitter 进行身份验证,同时询问用户名/电子邮件/密码的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)