问题描述
我试图在我的无服务器(/api
路由)next.js应用程序中实现Google登录。
我正在使用@passport-next/passport-google-oauth2
,next-connect
和passport
软件包。
我进行了很多搜索,找到了一些有用的在线链接,但我无法使其正常工作,并且我不确定此处应该进行的整个流程。
例如,我发现了那些:
- https://github.com/andycmaj/nextjs-passport-session-auth
- https://todayilearned.io/til/nextjs-with-passport-oauth-cookie-sessions
我有/api/auth/login
条路由用于常规登录。如果登录成功,则在用户响应上设置JWT
cookie。
对于Google登录,我添加了/api/auth/social/google
路由,并带有以下代码:
import passport from 'passport';
import { Strategy as GoogleStrategy } from '@passport-next/passport-google-oauth2';
import nextConnect from 'next-connect';
passport.use(new GoogleStrategy({
clientID: process.env.OAUTH_GOOGLE_CLIENT_ID,clientSecret: process.env.OAUTH_GOOGLE_CLIENT_SECRET,callbackURL: process.env.OAUTH_GOOGLE_CALLBACK_URL,scope: "https://www.googleapis.com/auth/plus.login",},(accesstoken,refreshToken,googleUserInfo,cb) => {
console.log('accesstoken,googleUserInfo');
cb(null,googleUserInfo);
}
));
export default nextConnect()
.use(passport.initialize())
.get(async (req,res) => {
passport.authenticate('google')(req,res,(...args) => {
console.log('passport authenticated',args)
})
})
和/api/auth/social/callback/google
路由,并带有以下代码:
import passport from 'passport';
import nextConnect from 'next-connect';
passport.serializeUser((user,done) => {
console.log('serialize')
done(null,user);
});
export default nextConnect()
.use(passport.initialize())
.get(async (req,res) => {
passport.authenticate('google',{
failureRedirect: '/failure/success',successRedirect: '/auth/success',})(req,(...args) => {
console.log('auth callback')
return true;
})
})
因此,发生的情况是,用户登录到他的Google帐户后将重定向到/auth/success
,并且控制台日志为:
accesstoken,googleUserInfo
serialize
所以我的问题是:
- 何时以及如何在响应中设置
JWT
cookie以“登录”用户? - 为什么
console.log('auth callback')
行永远不会运行?什么时候应该运行? - 与
console.log('passport authenticated',args)
相同
- 一个完整的流程在我的应用程序中应如何显示?
谢谢!
解决方法
我遇到了同样的问题。我仍在研究完整的实现,但根据 this thread 看来问题可能是应该将 Passport.authenticate 用作中间件:
// api/auth/social/callback/google
export default nextConnect()
.use(passport.initialize())
.get(passport.authenticate("google"),(req,res) => {
console.log('auth callback')
res.writeHead(302,{
'Location': '/auth/success'
});
res.end();
})
,
好吧,我不是Next.js专家,但是我有一个类似的“问题”,仅使用其他身份验证方法即可。
您会看到,该框架具有一种在身份验证过程中非常重要的方法,它们被称为: getInitialProps ,这是一个异步函数,可以作为静态方法添加到任何页面中,在初始渲染之前触发;
它看起来像这样:
static async getInitialProps(ctx) {
const res = await fetch('https://api.github.com/repos/vercel/next.js')
const json = await res.json()
return { stars: json.stargazers_count }
}
使用此 ctx 道具,它是一个带有{req,res}的对象,您可以用来提出请求以验证用户身份,然后可以使用 req 和lib next-cookies 来获取JWT令牌并检查其是否有效,然后,您可以返回一个对象,该对象将用作页面的道具(或全部)页面,如果您将 _app.js 包装在身份验证上下文中。
此外,不会调用您的“身份验证回调” ,因为您是在用户触发之前重定向用户的,这种情况不会发生。 “通过护照验证”
也是如此本文也可能对您有所帮助。 https://dev.to/chrsgrrtt/easy-user-authentication-with-next-js-18oe