I am currently making a web app that uses Vue.JS for the frontend part and Django for the backend. I'm using django-rest-framework to communicate between the client and the server.
I would like to specify that everything works fine when using Postman for testing my requests
When trying to login or register (those are only the two features I have implemented yet) The server sends back the following response:
"CSRF Failed: Origin checking failed - http://localhost:8080 does not match any trusted origins." Status: 403
The csrftoken cookie is there and I made sure it's sent
Here are some details on my setup
Requests are sent using Axios. In main.js
I overrode the following axios.defaults
axios.defaults.baseURL = 'http://localhost:8000';
axios.defaults.xsrfCookieName = 'csrftoken';
axios.defaults.xsrfHeaderName = 'X-CSRFToken';
axios.defaults.withCredentials = true;
And the login request is sent in this method in a Pinia user store:
async login(email, password)
{
try
{
let response = await axios.post('authentication/login/', {email: email, password:
password});
this.setUserData(response.data.id, response.data.email);
}
catch(error)
{
console.log(error);
}
},
Server side:
My User view is written the following way:
def UserAuthenticationView(APIView):
serializer_class = UserSerializer
def get(self, request):
#retrieve currently logged-in user
pass
def post(self, request):
#register new user in database
pass
@api_view(['POST])
def login(request):
# decode request sent as json
body = json.loads(request.body)
# make sure all fields are present
try:
email = body['email']
password = body['password']
except KeyError:
return Response("Email or password are missing", status=400)
# validateEmail() and validatePassword() are custom functions that check the format of both
# fields
if (not validateEmail(email) or not validatePassword(password)):
return Response("Email or password are missing", status=400)
user = authenticate(email=email, password=password)
# check if authentication worked
if user is None:
return Response("Failed to authenticate user", status=400)
else:
# log user on session and return it
login(request, user)
return Response(UserAuthenticationView.serializer_class(user).data)
Inside settings.py
I added the following line
CSRF_TRUSTED_ORIGINS = ["http://localhost:8080"]
But because my login view needs to access the body of the request I get an internal server error. From what I understand, the CSRF Middleware reads the body of the request first and I should use csrf_exempt()
to prevent this behaviour
So in urls.py
I tried the following with no success:
urlpatterns = [
path('', views.UserAuthenticationView.as_view()),
path('login/', csrf_exempt(views.UserAuthenticationView.login)),
What I don't understand either is that APIView is supposed to automatically csrf_exempt all views inside it but my register view, which corresponds to the post()
method of UserAuthenticationView doesn't work for the same reason.
CSRF_TRUSTED_ORIGINS
to['https://*', 'http://*']
?. This is not good practice, but if you still get the same error it may be a fault in the axios-defaults.