NextJs 使用 Next-Auth 对 DRF 进行身份验证

NextJs Authentication with Next-Auth against DRF

我有一个正在尝试从模板转移到 NextJs 前端的现有 Django 项目。我遇到了 Next-Auth-js,它在 Next Auth 中似乎不错。

但是,该文档似乎更多地关注与 JS 相关的后端身份验证。在此 example 之后,我已将 NEXTAUTH_URL 环境变量发送到我的 DRF 端点 localhost:8002。前端在 localhost:3000 上运行。虽然我的 _app.js 看起来像这样:

<Provider options={{site: process.env.NEXTAUTH_URL,}} session={pageProps.session}  >
  <Component {...pageProps} />
</Provider>

使用 Nav.js 进行测试,我将 signin/out href 更改为指向我的 Django 端点,但 next-auth-js 似乎忽略了这一点并将会话提取放置到我的前端 http://localhost:3000/api/auth/session 而不是 http://localhost:8002/api/auth/session.

对于如何使用 Django Rest Framework (DRF) correctly/securely 实施此身份验证的任何帮助,我将不胜感激

我认为 that is the way it should work, your nextjs site would be a kind of proxy/middleware to your django API client -> nextjs -> DRF, you should let it handle the sessions and for any action you need to do in your API for any authentication step, put code to hit those endpoints in the callbacks or events configuration, I think this tutorial 对于您的用例更准确

来自 docs

pages/api/auth/[...nextauth].js

import Providers from `next-auth/providers`
...
providers: [
  Providers.Credentials({
    // The name to display on the sign in form (e.g. 'Sign in with...')
    name: 'Credentials',
    // The credentials is used to generate a suitable form on the sign in page.
    // You can specify whatever fields you are expecting to be submitted.
    // e.g. domain, username, password, 2FA token, etc.
    credentials: {
      username: { label: "Username", type: "text", placeholder: "jsmith" },
      password: {  label: "Password", type: "password" }
    },
    authorize: async (credentials) => {
      // Add logic here to look up the user from the credentials supplied
      const user = { id: 1, name: 'J Smith', email: 'jsmith@example.com' }

      if (user) {
        // call your DRF sign in endpoint here
        // Any object returned will be saved in `user` property of the JWT
        return Promise.resolve(user)
      } else {
        // If you return null or false then the credentials will be rejected
        return Promise.resolve(null)
        // You can also Reject this callback with an Error or with a URL:
        // return Promise.reject(new Error('error message')) // Redirect to error page
        // return Promise.reject('/path/to/redirect')        // Redirect to a URL
      }
    }
  })
]

...

  events: {
    signOut: async (message) => { /* call your DRF sign out endpoint here */ },
  }

你可以在这里使用callbackshttps://next-auth.js.org/configuration/callbacks

callbacks: {
  async signIn(user, account, profile) {
    return true
  },
  async redirect(url, baseUrl) {
    return baseUrl
  },
  async session(session, user) {
    return session
  },
  async jwt(token, user, account, profile, isNewUser) {
    return token
  }
}

signIn回调中,您可以从提供商登录中获取accessToken和tokenId。在这里,调用您的 DRF API 并将这些令牌传递给您的 DRF,当您从 DRF 返回 access_tokenrefresh_token 时。将它们添加到您的用户实例。然后在 JWT 回调中,从 user 获取 accessrefresh 并将它们添加到 token

从一些博客上得到的

不过,您还需要处理刷新令牌。