1

我正在尝试在我的无服务器(/api路由)next.js 应用程序中实现 Google 登录。
我正在使用@passport-next/passport-google-oauth2,next-connectpassport包。
我进行了很多搜索,并在网上找到了一些有用的链接,但我无法让它工作,而且我不确定这里应该发生的整个流程。
例如,我发现了那些:

我有/api/auth/login定期登录的路线。如果登录成功,我将JWT在用户响应中设置 cookie。

对于谷歌登录,我添加了/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, refreshToken, 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, res, (...args) => {
            console.log('auth callback')
            return true;
        })
    })

所以发生的情况是用户/auth/success在登录到他的谷歌帐户后被重定向到,并且控制台日志是:

accessToken, refreshToken, googleUserInfo
serialize

所以我的问题是:

  1. 何时以及如何JWT在响应“登录”用户时设置 cookie?
  2. 为什么这条线console.log('auth callback')永远不会运行?它应该什么时候运行?
  3. 同样对于console.log('passport authenticated', args)
  4. 我的应用程序中的完整流程应该是什么样子?

谢谢 !

4

2 回答 2

1

我有同样的问题。我仍在研究完整的实现,但根据这个线程看起来问题可能是 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();
  })
于 2021-02-09T17:43:48.583 回答
0

好的,我不是 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 prop,它是一个带有 {req, res} 的对象,您可以使用它来发出请求来验证用户,然后,您可以使用req和 lib next-cookies来获取 JWT 令牌并检查是否它是有效的,然后,您可以返回一个对象,该对象将用作您的页面(或所有页面,如果您将_app.js包装在身份验证上下文中)的道具。

此外,您的“身份验证回调”没有被调用,因为您在用户触发之前重定向了用户,而这并没有发生。'passport authenticated'也一样

这篇文章也可能对您有所帮助。 https://dev.to/chrsgrrtt/easy-user-authentication-with-next-js-18oe

于 2020-11-04T22:23:40.037 回答