I am using session authentication in my Django – React application.
But no session cookie is stored in the cookie storage.
(A csrf token cookie is stored!)
I cleared the local storage / session storage and the cookies
I tried with different browsers
On the frontend Part,
I make a post request for the login:
axios.defaults.xsrfCookieName = "csrftoken";
axios.defaults.xsrfHeaderName = "X-CSRFToken";
axios.defaults.withCredentials = true;
const client = axios.create({
baseURL: "http://127.0.0.1:8000",
});
function submitLogin(e) {
e.preventDefault();
setIsLoading(true);
client
.post("/login", {
email: email,
password: password,
})
.then(function (res) {
setCurrentUser(true);
window.location.reload(); // Refresh the page after login
})
.catch(function (error) {
setIsLoading(false);
});
}
I get a status code 200, user is logged in everything seems to work fine.
(When opening the application in a incognito window the log in is not working!)
Also I get a SameSite attribute error in dev tools:
Indicate whether to send a cookie in a cross-site request by
specifying its SameSite attribute
even though I set everything in settings.py:
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
SESSION_COOKIE_SECURE = False # Set it to False during development with HTTP
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = 'None' # If using cross-site requests
SESSION_COOKIE_SECURE = True # If using HTTPS
note that when setting
SESSION_COOKIE_SAMESITE = 'lax' or 'strict'
and removing
SESSION_COOKIE_SECURE = True # If using HTTPS
the log in no longer works
I also tried without setting the SESSION_ENGINE and using the default but that makes no difference (the login works but no cookie)
On the backend site I use a custom User model
This is my UserLogin View:
class UserLogin(APIView):
permission_classes = (permissions.AllowAny,)
authentication_classes = (SessionAuthentication,)
def post(self, request):
data = request.data
assert validate_email(data)
assert validate_password(data)
serializer = UserLoginSerializer(data=data)
if serializer.is_valid(raise_exception=True):
user = serializer.check_user(data)
login(request, user)
return Response(serializer.data, status=status.HTTP_200_OK)
I included corsheaders in the INSTALLED_APPS and in the MIDDLEWARE right at the top I put
"corsheaders.middleware.CorsMiddleware",
also I added:
CORS_ALLOW_ALL_ORIGINS = True
CORS_ALLOW_CREDENTIALS = True
All other requests from frontend to backend work fine!
I am also pretty sure rest framework is configured correctly I included rest_framework in the INSTALLED_APPS and:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
),
}
Why is no session cookie stored?
2
Answers
try this way :
in this I remove the duplicate line
SESSION_COOKIE_SECURE
When you use
SessionAuthentication
, by default django requires 2 thingsIf these do not match, then an error is raised, so, there is the documentation to make it authenticate in the correct way.
When you are using
SessionAuthentication
, you are using Django’s authentication which usually requires CSRF to be checked. So you must pass the CSRF token in the X-CSRFToken header.This documentation provides more information on retrieving the CSRF token and sending it in requests. The CSRF token is saved as a cookie called
csrftoken
that you can retrieve from a HTTP response.If you cannot retrieve the CSRF cookie, this is usually a sign that you should not be using SessionAuthentication (use TokenAuthentication or OAuth 2.0 instead).