1

我最近尝试将 Nuxt.js 与 Django 结合起来。Nuxt.js 有一个名为 Nuxt Auth 的模块(我使用 @nuxtjs/auth-next),它非常简单易用。

但是,当我$auth.loginWith(...)在 Django APIView 中使用时尝试获取帖子数据时遇到了问题。当我打印出来时request.POST,它返回一个空的 QueryDict。当我使用标准 DRF 表单登录时,我按预期获得了我的令牌(我使用 JWT 进行身份验证)。

我首先认为我在 Nuxt.js 前端做错了什么,所以我在 GitHub 上克隆了一些存储库,看看他们是如何做到的(tickstudiuammezie)。然后我尝试将他们的前端与我的后端结合起来。我还在YouTube上看了一个教程。

仍然是同样的问题...这就是为什么我认为这是 Nuxt + Django 特有的问题,因为否则,其他 repos 会起作用,对吧?或者,也许我只是每次都做错了……

这是我使用标准 DRF 表单登录时得到的结果:

HTTP 200 OK
Allow: POST, OPTIONS
Content-Type: application/json
Vary: Accept
{
    "username": "admin",
    "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwiZW1haWwiOiJhbmRyZWFzLmdlcmFzaW1vdzEyQGdtYWlsLmNvbSIsImV4cCI6MTYyMjc5NjQ2N30.XQ58Fo0nOS2C44SRQG5A2vEDT0fOXJTIrHG8XNaxzBo"
} 

这是我在 Django 中的登录 API:

class LoginAPIView(GenericAPIView):

serializer_class = LoginSerializer

def post(self, request, *args, **kwargs):

    print(request.POST) # prints an empty QueryDict

    username = request.POST.get('username', None)
    password = request.POST.get('password', None)

    user = authenticate(username=username, password=password)

    if user:
        serializer = self.serializer_class(user)
        return Response(serializer.data, status=status.HTTP_200_OK)
    return Response({'message':'Bad credentials!'}, status=status.HTTP_401_UNAUTHORIZED)

这是控制台中的输出,当我尝试使用 Nuxt 登录时:

<QueryDict: {}>
Unauthorized: /api/accounts/login/
[03/Jun/2021 10:35:28] "POST /api/accounts/login/ HTTP/1.1" 401 30

这是我在 Nuxt 中的登录表单脚本:

export default {
  data() {
    return {
      valid: false,
      userInfo: {
        username: "",
        password: "",
      },
    };
  },

  methods: {
    loginUser() {
    this.$auth.loginWith("local", {
        data: this.userInfo,
      }).catch((err) => console.log(err));
    },
  },
};

这是我nuxt.config.js文件的一部分:

modules: [
    // https://go.nuxtjs.dev/axios
    '@nuxtjs/axios',
    '@nuxtjs/auth-next'
  ],

  // Axios module configuration: https://go.nuxtjs.dev/config-axios
  axios: {
    baseURL: 'http://127.0.0.1:8000/api/'
  },

  // authentication module configuration
  auth: {
    strategies: {
      local: {
        endpoints: {
          login: { url: 'accounts/login/', method: 'post', propertyName: false },
          user: { url: 'accounts/authenticate/', method: 'get', propertyName: false },
          logout: { url: 'accounts/logout/', method: 'post' }, // method: 'delete'
        },
        tokenType: 'bearer',
      }
    }
  },
  ...

我使用 Django 3.2.3、DRF 3.12.4、Nuxt.js 2.15.3 和 Nuxt Auth 5.0.0-1622309801.87126e3。

编辑:

感谢 Kissu,当我尝试使用 Nuxt 登录时,我发现 CSRF Token 丢失了。请求有效载荷:

{password: "some password", username: "admin"}

这是我使用标准 DRF 表单成功登录时的请求负载。我发现它使用multipart/formdata而不是application/json标准。当我使用后者时,它不起作用。

csrfmiddlewaretoken: X0FSeyS01dT8vgFK8eZhsXh5IYcDm8uGuqyh5XDOapoNMP8gZhQDcOacfsPYtsSp
username: admin
password: some password

我将我的 axios 配置编辑为:

axios: {
  baseURL: 'http://127.0.0.1:8000/api/',

  headers: {
    'X-CSRFToken': 'csrftoken',
  },
  xsrfCookieName: 'csrftoken',
  xsrfHeaderName: 'X-CSRFToken',
},

它仍然不起作用,但我现在得到一个400 Bad Request错误而不是 401。在标题中,我可以找到这个:X-CSRFToken: csrftoken。这意味着没有正确插入 csrf 令牌。但是,它确实可以正确插入到普通的 Vue 应用程序中。

View好消息:当我继承标准 Django而不是 DRFGenericAPIView和 Vue 而不是 Nuxt时,我发现一切正常。

我现在的问题是:如何在 Nuxt 应用程序中设置 csrf 令牌,为什么它不能application/json在 DRF 中使用?我在互联网上没有发现任何对我有用的东西。

4

0 回答 0