我最近尝试将 Nuxt.js 与 Django 结合起来。Nuxt.js 有一个名为 Nuxt Auth 的模块(我使用 @nuxtjs/auth-next),它非常简单易用。
但是,当我$auth.loginWith(...)
在 Django APIView 中使用时尝试获取帖子数据时遇到了问题。当我打印出来时request.POST
,它返回一个空的 QueryDict。当我使用标准 DRF 表单登录时,我按预期获得了我的令牌(我使用 JWT 进行身份验证)。
我首先认为我在 Nuxt.js 前端做错了什么,所以我在 GitHub 上克隆了一些存储库,看看他们是如何做到的(tickstudiu,ammezie)。然后我尝试将他们的前端与我的后端结合起来。我还在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 中使用?我在互联网上没有发现任何对我有用的东西。