![](/img/trans.png)
[英]How to send CSRF Cookie from React to Django Rest Framework with Axios
[英]Django Rest Framework doesn't recognize CSRF cookie sent from a a React app using Axios
我已經擔任后端開發人員很多年了,但是現在我也想學習前端,因此我選擇React作為我的前端框架。 我已經花了兩天的時間來學習如何使用Axios將來自React應用的請求發送到Django Rest Framework后端,並且已經遇到了csrf cookie問題。 到目前為止,我已經發布了幾個問題,最后,我可以發送一個正確的格式請求,該請求被后端接受了……只是得到了一個Forbidden (CSRF token missing or incorrect.)
錯誤。
我想我獲取和使用csrf令牌的方法可能不正確,因此,我感謝您指出我的錯誤並教我解決方法。
首先,我向后端發送GET
請求,其唯一目的是獲得csrf令牌 (我這樣做),然后將cookie設置為此類令牌:
class App extends Component {
render() {
const axios = require('axios');
axios.get('http://127.0.0.1:8000/es/api/hand_shake/')
.then(function (response) {
Cookies.set('csrftoken', response['data']['cookie']);
console.log(response);
})
.catch(function (error) {
console.log(error);
})
return (
<div className="App">
<LoginModal />
</div>
);
}
}
export default App;
其次,在另一個模塊中,我從cookie中獲取令牌,並在POST
請求中使用它:
handleClick() {
const axios = require('axios');
var csrfCookie = Cookies.get('csrftoken');
console.log(csrfCookie)
axios.post('http://127.0.0.1:8000/es/api-auth/login/',
{
next: '/',
username: 'admin@admin.com',
password: 'Cancun10!',
},
{
headers: {
'x-xsrf-token': csrfCookie,
},
withCredentials: true,
}
)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
})
}
最后,我有后端可以接受請求,但是卻收到錯誤信息Forbidden (CSRF token missing or incorrect.)
。
以我的方式獲取令牌然后以嘗試的方式使用令牌是否正確?
我發現的唯一解決方案是使登錄過程免於csrf驗證,但是我不得不放棄Django Rest Framework默認身份驗證功能(如果有人知道如何使用DRF默認身份驗證,請分享),並實現我自己的自定義身份驗證視圖。
我創建了一個ViewSet
並用csrf_exempt
裝飾它,如下所示:
from django.views.decorators.csrf import csrf_exempt
class LoginViewSet(viewsets.ViewSet):
permission_classes = ()
@csrf_exempt
def post(self, request):
from PhotosManagerApp.email_backend import EmailBackend
email_backend_instance = EmailBackend()
user = email_backend_instance.authenticate(request, username=request.data['username'], password=request.data['password'])
if user:
try:
usr_token = Token.objects.get(user=user)
except:
usr_token = None
else:
usr_token = None
return Response({'token': str(usr_token)})
您還必須在urls.py
裝飾視圖:
path('login/', csrf_exempt(views.LoginViewSet.as_view({'post': 'post'}))),
在找到正確的配置之前,我對Django settings.py
遇到了很多麻煩:
from corsheaders.defaults import default_headers
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOW_HEADERS = default_headers + (
'xsrfheadername',
'xsrfcookiename',
'content-type',
'x-csrftoken',
)
CORS_ORIGIN_ALLOW_ALL = True
CSRF_COOKIE_NAME = "csrftoken"
我遇到很多麻煩,直到發現必須將default_headers
添加到CORS_ALLOW_HEADERS
。
現在,只需確保使用withCredentials = false
發送您的請求:
handleClick() {
const axios = require('axios');
//axios.defaults.withCredentials = true;
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN";
axios.defaults.xsrfCookieName = "csrftoken";
axios.post('http://127.0.0.1:8000/es/api/login/',
{
username: 'admin@admin.com',
},
)
.then(function (response) {
Cookies.set('token', "Token ".concat(response.data.token), {"expires": 10})
console.log(response);
})
.catch(function (error) {
console.log(error);
})
}
這對我有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.