NextJs 身份验证与针对 DRF 的 Next-Auth
Posted
技术标签:
【中文标题】NextJs 身份验证与针对 DRF 的 Next-Auth【英文标题】:NextJs Authentication with Next-Auth against DRF 【发布时间】:2021-02-03 22:11:23 【问题描述】:我有一个退出的 Django 项目,我正试图从模板转移到 NextJs 前端。我遇到了 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 进行测试,我将登录/输出 href 更改为指向我的 Django 端点,但似乎 next-auth-js 忽略了这一点,并将会话提取放置到我的前端 http://localhost:3000/api/auth/session
而不是http://localhost:8002/api/auth/session
.
对于如何使用 Django Rest Framework (DRF) 正确/安全地实施此身份验证的任何帮助,我将不胜感激
【问题讨论】:
NEXTAUTH_URL 的值是多少? NEXTAUTH_URL=localhost:8002/api/account/auth/login in .env 【参考方案1】:您可以在此处使用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
在signIn
回调中,可以通过provider登录获取accessToken和tokenId
。在这里,调用您的 DRF API 并将这些令牌传递给您的 DRF,当您从 DRF 取回 access_token
和 refresh_token
时。将它们添加到您的用户实例。然后在JWT
回调中,从user
获取access
和refresh
并将它们添加到token
中
从某个博客得到这个
不过,您还需要处理刷新令牌。
【讨论】:
【参考方案2】:我认为that is the way it should work,您的 nextjs 站点将是您的 django API client -> nextjs -> DRF
的一种代理/中间件,您应该让它处理会话以及您需要在 API 中为任何身份验证步骤执行的任何操作,将代码放在callbacks 或events 配置中,我认为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 */ ,
【讨论】:
我已经访问过与我的案例无关的教程 b4。我正在使用 Providers.Credentials 和现有的登录/注销端点 (DRF),并创建了应该使用 next-auth signIn() 进行登录的自定义 login.tsx。 @Paullo 我看不出它是如何不相关的,你不应该期望调用 DRF,你应该在Provider.Credentials
授权方法和 signOut
事件中自己调用这些端点
我已经通过了这些阶段,但是如果您关注此讨论 github.com/nextauthjs/next-auth/issues/280,就会发现这是一个现有问题。不过,这个讨论线程很少有其他人提供帮助。
@Paullo 如果你用你的新进展更新你的问题会很好以上是关于NextJs 身份验证与针对 DRF 的 Next-Auth的主要内容,如果未能解决你的问题,请参考以下文章