将 next-auth 与 Google OAuth 和存储在数据库中的用户一起使用的正确方法是什么?

Ray*_*lez 3 next.js next-auth

我是新手next-auth,我正在寻求帮助。

我已经添加了 Google OAuth 提供程序,现在当我运行时signIn("google")在前端运行函数时,它会自动将我带到 google 的登录页面,并以某种方式让我登录,而无需触摸我的数据库。

当谷歌身份验证完成后,我需要能够在我的数据库中创建一个新用户,或者检索现有用户(如果他们之前已经注册过)(因为我需要存储有关用户的各种自定义信息,而不仅仅是他们的电子邮件)。

我想让用户的信息在钩子session的对象上可用useSession()。现在我看到某种默认用户信息(带有nameemailimage我未定义的 、 和字段

当我使用常规 Express 服务器和 Passport 时,代码看起来有点像这样:

const googleAuth = new GoogleStrategy(
  {
    clientID: process.env.GOOGLE_CLIENT_ID,
    clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    callbackURL: "/api/v1/profiles/google/callback",
  },
  async (req, accessToken, refreshToken, profile, done) => {
    const existingProfile = await Profile.findOne({ email: profile.emails[0].value })
    /* Found user, return him and move along. */
    if (existingProfile) return done(null, existingProfile)

    /* Haven't found profile with this googleId, create a new one. */
    const newProfile = await new Profile({
      googleId: profile.id,
      email: profile.emails[0].value,
    })
    newProfile.save()

    done(null, newProfile)
  }
)
Run Code Online (Sandbox Code Playgroud)

因此,我仍然会在数据库中创建用户,并在登录时检索他们的信息,以便我可以将其发送给客户端。

当我使用无服务器时,这种代码应该去哪里next-auth

第二个但相关的问题 - 在对象中提供给我的默认用户对象是什么session?带有nameemailimage字段的那个next-auth似乎是为我创建的?如何让它使用我从数据库返回的用户对象?

(我已尽力浏览教程和示例,但找不到清楚解释这一点的教程和示例。)

小智 10

我不知道你是否还需要这个,但我希望它对某人有所帮助:

Oauth 有点混合了登录和注册,因此如果您想要进行 Google 身份验证,您可能想要做的是在 中创建登录函数的回调/api/auth/[...nextauth].js,然后获取帐户和配置文件作为参数并访问其提供程序。

async signIn({account, profile}) {
    if(account.provider === 'google') {
        //check if user is in your database
        if(user NOT in DB) {
            //add your user in DB here with profile data (profile.email, profile.name)
        }
        return true
    }
Run Code Online (Sandbox Code Playgroud)

您总是想返回,true因为无论它是否在您的数据库中,您总是希望独立登录。

关于session对象,您还可以添加回调并访问默认值session(您可以修改),token并且user. 在这里,您可以从数据库中检索所需的所有信息,将其添加到会话对象中并返回它。

async session({ session, token, user }) {
    const newData = DB.find(...).data
    session.newfield = newInfo
    return session
}
Run Code Online (Sandbox Code Playgroud)