使用 NextJS 前端表单进行 Django 后端身份验证 - 最佳实践

gri*_*igs 8 django django-rest-framework reactjs next.js

我有一个在 Django 中构建的 API 中心和一个在 NextJS 中构建的前端应用程序。我目前正在对 Nextjs 中的 Django API 进行身份验证,我对最佳实践感到好奇。

目前,NextJS 应用程序将用户用户名/密码发布到端点。此端点返回用户令牌或说明问题的错误。

反应

  const login = async () => {
    let token = await axios.post('/api/accounts/', {
      email: email,
      password: password
    }).then(r => r.data.token).catch(function (error) { console.log(error) })

      if (token) {
        router.push({
            pathname: '/home/',
            query: { token: token },
          })
        }
      }
Run Code Online (Sandbox Code Playgroud)

nexjs服务器api/accounts

export default async (req, res) => {
  if (req.method === 'POST') {
    try {
      // retrieve payment intent data
      const {data} = await axios.post('https://website/api/api-token-auth/', req.body)
      res.status(200).send(data)
    } catch (err) {
      res.status(500).json({ statusCode: 500, message: err.message })
    }
  } else {
    res.setHeader('Allow', 'POST')
    res.status(405).end('Method Not Allowed')
  }
}
Run Code Online (Sandbox Code Playgroud)

Django API

@csrf_exempt
@api_view(["POST"])
@permission_classes((AllowAny,))
def obtain_auth_token(request):
    email = request.data.get("email")
    password = request.data.get("password")
    if email is None or password is None:
        return Response({'error': 'Please provide both email and password'},
                        status=HTTP_400_BAD_REQUEST)
    user = authenticate(email=email, password=password)
    if not user:
        return Response({'error': 'Invalid Credentials'},
                        status=HTTP_404_NOT_FOUND)

    token, _ = Token.objects.get_or_create(user=user)
    return Response({'token': token.key},
                    status=HTTP_200_OK)
Run Code Online (Sandbox Code Playgroud)

一旦我收到令牌,我就会将用户推送到主页。

我的问题是:

  1. 我对用户进行身份验证的方式是执行此操作的好方法吗?我是否忽略了什么?这是我第一次尝试对我构建的东西进行身份验证,所以我想做到这一点。

  2. 我应该如何存储这个令牌?身份验证信用方面的“最佳实践”是什么?我考虑过将令牌传递给每个需要它的组件。我也研究过使用 LocalStorage,但再次不确定大多数人在这些情况下会做什么。

如果您能提供任何帮助,我们将不胜感激!

提前致谢!

Jea*_*ier 0

我对用户进行身份验证的方式是执行此操作的好方法吗?我是否忽略了什么?这是我第一次尝试对我构建的东西进行身份验证,所以我想做到这一点。

  • Python 后端看起来非常好。您的代码的唯一缺点是您正在重新发明轮子。令牌身份验证已经实现,因此您不必担心实现它,您可以直接使用TokenAuthentication

  • nexjs 服务器看起来...没用?为什么需要它作为前端和 API REST 之间的中间服务?无论如何,您应该注意到响应重定向覆盖身份验证失败,状态代码为 500:

    try {
        // retrieve payment intent data
        const {data} = await axios.post('https://website/api/api-token-auth/', req.body)
        res.status(200).send(data)
     } catch (err) {
        // if err status code is 404 e.g. bad credentials, response status is 500 where it should be 404.
        res.status(500).json({ statusCode: 500, message: err.message })
     } 
    
    Run Code Online (Sandbox Code Playgroud)

我应该如何存储这个令牌?身份验证信用方面的“最佳实践”是什么?我考虑过将令牌传递给每个需要它的组件。我也研究过使用 LocalStorage,但再次不确定大多数人在这些情况下会做什么。

不要使用cookie来避免CSRF攻击。由于您已经在使用 HTTPS,因此本地存储是“快速且简单”的答案。本地存储的一个缺点是您的令牌很容易受到 XSS 攻击,但如果发生此类攻击,您已经受到严重损害。(XSS 攻击者可以拦截密码和登录信息,那么访问令牌有什么意义呢?)。您可以在这里找到更多信息