Единственное решение, которое я нашел, - освободить процесс входа в систему от проверки 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);
})
}
Вот что у меня сработало.