我应该在NextAuth authOptions.callbacks中执行数据库查找吗?

t0ybt7op  于 2023-06-22  发布在  其他
关注(0)|答案(2)|浏览(142)

我想在nextAuth会话中存储用户的idrole,是否应该在authOptions.callbacks期间在数据库中为用户执行查找?
我在Github discussions和文档中找到的共识是,将信息从callback.jwt(token)传递到callback.session(token)。问题是,当我使用Google或Github OAuth提供程序时,他们只提供了一个带有以下字段的jwt(token)参数:name, email, picture, sub, iat, exp, jti和jwt回调中提供的其余args(useraccountprofile)值是undefined
由于这些提供的参数都没有我需要的字段,我应该在我的jwt token中使用返回的唯一email来在callback. jwt()中执行数据库查找,将返回的mongodb文档的id和role附加到token,然后将它们附加到下面的会话返回值吗?

// [...nextAuth].ts authOptions
  ...
  session: {
    strategy: "jwt",
  },
  callbacks: {
    async jwt({ token, user, account, profile }) {
      // user, account, and profile are undefined when using OAuth
      // token returns { user: "a", email: "b", image: "c" }
      
      // should I perform a database lookup here, find the matching user via email
      // and then append the found user.id and user.role into token? 
      return token;
    },
    async session({ session, user, token }) {
      // then insert those id and role key/values into session here before returning? 
      return session;
    },
  },

在authOptions.callback中执行数据库查找是个好主意吗?这是惯例吗?

Extra-为什么nextAuth不通过自动匹配电子邮件来查找用户?
  • --已解决*

由于我使用MongoDB作为我的数据库,我有MongoDB适配器设置。我最初认为适配器会在通过OAuth登录时通过电子邮件在我的数据库中执行匹配用户的查找,然后在我的callback.jwt(user)参数中显示匹配用户。然而,我的用户参数在使用OAuth时是undefined,但在使用Credentials时存在。当鼠标悬停在callback.jwt(user)上时,我对intellisense消息感到更加困惑,因为它似乎表明了一些矛盾的东西?

// intellisense for callback.jwt(user)
Either the result of the OAuthConfig.profile or the CredentialsConfig.authorize callback.

我应该期待.profile成为我的数据库用户吗?目前,它返回undefined。是我的适配器不能正常工作,还是这种行为依赖于底层的OAuth提供程序,或者我只是误解/错误实现了该功能?

x6492ojm

x6492ojm1#

.profile不是您的数据库用户。其类型:

/** The OAuth profile returned from your provider */
export interface Profile {
    sub?: string;
    name?: string;
    email?: string;
    image?: string;
}

这来自OAuth提供者。必须在jwt回调中获取数据库用户

callbacks: {
  async jwt({ token, user }) {
    // make a query based on your logic
    const dbUser = await User.findOne({tokenId:token.id})
    
    ...
  },
0lvr5msh

0lvr5msh2#

我继续修补NextAuth,并了解到所有适配器都有一些约定。当您使用“Credentials”和/或OAuth提供者时,您的数据库用户实际上会被查找并返回。在jwt回调中,user将返回两种提供程序类型的查找结果。只要确保使用条件检查来 Package 它,如下所示。
值得注意的是,这需要您设置一个数据库,就像NextAuth能够(自动)创建/更新users/accounts一样,它可以在登录和注册期间查找匹配的集合/行。这意味着你不必在jwt回调中执行另一次查找来获取你的用户信息,因为你的数据库信息在登录时会通过回调流自动返回给你。
此外,虽然我有一个数据库,根据文档,你可以覆盖默认的“数据库”策略与session: {strategy: 'jwt' }这是必要的,如果你仍然想登录和注册用户通过电子邮件/密码凭据。

// here is the relevant code within AuthOptions

  session: {
    strategy: "jwt",
  },
  callbacks: {
    async jwt({ token, user }) {
      if (user) {
        token.id = user.id;
        token.role = user.role || null;
      }
      return token;
    },
    async session({ session, token }) {
      session.user.userId = token.id as string;
      session.user.role = token.role as string;
      return session;
    },
  },

相关问题