简体   繁体   English

NextJs 身份验证与针对 DRF 的 Next-Auth

[英]NextJs Authentication with Next-Auth against DRF

I have an exiting Django project that I am trying to move from templates to NextJs frontend.我有一个退出的 Django 项目,我正试图将它从模板转移到 NextJs 前端。 I came across Next-Auth-js which seems to be nice in Next Auth.我遇到了 Next-Auth-js,它在 Next Auth 中似乎很好。

However, the doc seems to focus more with JS related Backend Auth.但是,该文档似乎更关注与 JS 相关的后端身份验证。 Following this example I have sent the NEXTAUTH_URL environment variable to my DRF Endpoint localhost:8002.按照这个示例,我已将 NEXTAUTH_URL 环境变量发送到我的 DRF 端点 localhost:8002。 While the frontend runs on localhost:3000.而前端在 localhost:3000 上运行。 While my _app.js looks like this:虽然我的 _app.js 看起来像这样:

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

Using the Nav.js for a test, I changed the signin/out href to point to my Django endpoints but it seems next-auth-js ignores this and places a session fetch to my frontend http://localhost:3000/api/auth/session instead of the the http://localhost:8002/api/auth/session .使用Nav.js进行测试,我将登录/输出 href 更改为指向我的 Django 端点,但似乎 next-auth-js 忽略了这一点,并将会话提取放置到我的前端http://localhost:3000/api/auth/session而不是http://localhost:8002/api/auth/session

I will appreciate any assistance on how I can correctly/securely implement this authentication using Django Rest Framework (DRF)对于如何使用 Django Rest Framework (DRF) 正确/安全地实现此身份验证的任何帮助,我将不胜感激

I think 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 is more accurate for your use case我认为这是它应该工作的方式,您的 nextjs 站点将是您的 django API client -> nextjs -> DRF的一种代理/中间件client -> nextjs -> DRF ,您应该让它处理会话以及您需要在您的用于任何身份验证步骤的 API,在回调事件配置中放置代码以命中这些端点,我认为本教程对您的用例更准确

from the docs文档

pages/api/auth/[...nextauth].js页面/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 */ },
  }

You can use callbacks here.您可以在此处使用callbacks https://next-auth.js.org/configuration/callbacks https://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
  }
}

in signIn callback, you can get accessToken and tokenId from provider login.signIn回调中,您可以从提供者登录中获取 accessToken 和tokenId Here, call your DRF API and pass those tokens to your DRF and when you get back the access_token and refresh_token from DRF.在这里,调用您的 DRF API 并将这些令牌传递给您的 DRF,当您从 DRF 取回access_tokenrefresh_token时。 Add them to your user instance.将它们添加到您的用户实例。 And then in JWT callback, get the access and refresh from user and add them into token然后在JWT回调中,从user获取accessrefresh并将它们添加到token

Got this from some blog从一些博客上得到这个

在此处输入图片说明

Though, you also need to handle the refresh token.不过,您还需要处理刷新令牌。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM