[英]{detail: 'CSRF Failed: CSRF token missing.'} Django and React
即使提供了 csrf,它在前端根本無法識別它(注意它在后端完美運行,但不是前端)
視圖.py:
class CheckAuthenticated(views.APIView):
def get(self, request):
if request.user.is_authenticated:
return Response("Authenticated")
else:
return Response("Not Authenticated",status=401)
class PostView(viewsets.ModelViewSet):
serializer_class = serializer.PostSerializer
def get_queryset(self):
queryset = models.Post.objects.all()
return queryset
@method_decorator(ensure_csrf_cookie,csrf_protect)
def create(self,request):
authentication_classes = [SessionAuthentication]
permissions_classes = [IsAuthenticated]
post = serializer.PostSerializer(data=request.data)
if post.is_valid():
title = post.data['title']
description = post.data['description']
models.Post.objects.create(title=title,description=description,user=User.objects.first())
return Response("post created successfully.")
return Response("post creation failed.")
我還有一個接收 csrf 令牌的資源:
class GetCSRFToken(views.APIView):
permission_classes = [AllowAny, ]
@method_decorator(ensure_csrf_cookie)
def get(self, request, format=None):
return Response("Success")
在 urls.py 中:
urlpatterns = [
path('csrf/',views.GetCSRFToken.as_view(),name='csrf'),
path('isauthenticated/',views.CheckAuthenticated.as_view(),name='authenticated'),
]
現在在前端:
let handleSubmit = (e)=>{
e.preventDefault()
console.log(Cookies.get('csrftoken'))
axios.post('http://127.0.0.1:8000/posts/',post,{withCredentials:true},{headers:{'X-CSRFToken':Cookies.get('csrftoken')}}).then((res)=>{
console.log(res.data)
}).catch((e)=>{
console.log(e.response.data)
console.log(Cookies.get('csrftoken'))
})
}
useEffect(()=>{
axios.get('http://127.0.0.1:8000/posts/').then((res)=>{
setPostList(res.data)
})
axios.get('http://127.0.0.1:8000/csrf/',{headers:{Authorization:null},withCredentials:true})
},[])
csrf 正在開發控制台中打印
任何想法?
編輯我的 csrf 設置,因為有人在評論中要求:
ALLOWED_HOSTS = ['*']
ACCESS_CONTROL_ALLOW_ORIGIN = '*'
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
ACCESS_CONTROL_ALLOW_CREDENTIALS = True
ACCESS_CONTROL_ALLOW_METHODS = '*'
ACCESS_CONTROL_ALLOW_HEADERS = '*'
'''
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_PATH = '/'
'''
CSRF_COOKIE_SAMESITE = 'Strict'
CSRF_TRUSTED_ORIGINS = [ "http://127.0.0.1:3000",'http://127.0.0.1:8000']
編輯:我發現在 settings.py 我在 drf 中的身份驗證有問題:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
]
}
這就是導致問題的原因,但是如果我嘗試更改為BasicAuthentication
之類的,即使我登錄了,我也會未經授權
我想這是解決方案的一半,也就是找到問題所在。
再次檢查您的代碼后,我想我找到了問題所在。 您對 axios 的要求不正確。
axios.post(
'http://127.0.0.1:8000/posts/',
post,
{withCredentials:true},
{headers:{
'X-CSRFToken':Cookies.get('csrftoken')}}
).then((res)=>{
...
現在檢查Axios API 。
axios.post(url[, data[, config]])
如果一一匹配。
網址 - 'http://127.0.0.1:8000/posts/'
data - post(我猜這是保存數據的變量,我建議你重命名它)
配置 - {withCredentials:true}
直到我了解您的 cookie 已發送(由於withCredentials:true
),但您的標頭未發送。 axios 會忽略它們。
因此,您必須將所有配置放在同一個對象中。 例如使用變量:
const postRequestConf = {
withCredentials: true,
headers: {
'X-CSRFToken': Cookies.get('csrftoken')
}
}
如果需要,可以將xsrfHeaderName: 'X-CSRFToken'
和xsrfCookieName: 'csrftoken'
添加到對象中。 檢查請求配置。
和請求。
axios.post(
'http://127.0.0.1:8000/posts/',
renamedVariable,
postRequestConf
).then( res => {...})...
現在,請求必須發送此數據。 您可以在 DevTools > Network 中驗證它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.