django-rest-frameworkaxioshttpcookiedjango-rest-framework-simplejwtdj-rest-auth

simpleJWT and dj-rest-auth Cookie based authorization


Between dj-rest-auth and simpleJWT I have been able to send the set-cookie messages, store the cookies in the browser, and send them back with each request (Axios' with credentials = true), but it seems like the back-end, no matter what I do, it is always expecting the Authentication Bearer Token.

I see on the github code, that the rest_framework_simplejwt.authentication.JWTAuthentication authentication class is only checking for the Authentication: Bearer Token header, but there is no way to do it directly with the cookies (no authentication header).

In fact, by default, it seems like Www-Authenticate is bearer dependent, and when using the dj-rest-framework JWTCookieAuthentication class is not overriding the authentication method.

Does anyone know how should the setting.py file should be configured to do so out-of-the-box, or is it mandatory to overwrite the authentication classes or create a custom one?

Thanks!

This is my dj-rest-auth cofig and simpleJWT in my settings.py

REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'] = [
        # 'rest_framework_simplejwt.authentication.JWTAuthentication',
        'dj_rest_auth.jwt_auth.JWTCookieAuthentication',
    ]

REST_AUTH = {
    'USE_JWT': True,
    'JWT_AUTH_SECURE': True,
    'JWT_AUTH_COOKIE': 'my-auth',
    'JWT_AUTH_REFRESH_COOKIE': 'my-refresh-token',
    'JWT_AUTH_HTTPONLY': True,
    'JWT_AUTH_SAMESITE': 'None',
}

Solution

  • I found the problem:

    It seems like in dj-rest-auth's jwt_auth library the cookie class has not been updated for the new cookies setup declaration introduced since v.3.

    Since version 3, there is a new configuration in the settings using the REST_AUTH dictionary. Nevertheless, dj-rest-auth/dj_rest_auth/jwt_auth.py is still checking the cookies from v2:

    ...
    def authenticate(self, request):
            cookie_name = api_settings.JWT_AUTH_COOKIE
    ...
    

    As it is now located in the dictionary, I extended the class like this, and it worked:

    from rest_framework_simplejwt.authentication import JWTAuthentication
    from rest_framework.authentication import CSRFCheck
    from rest_framework import exceptions, serializers
    from dj_rest_auth import jwt_auth
    from django.conf import settings
    
    class CustomCookieAuthentication(jwt_auth.JWTCookieAuthentication):
    
        def authenticate(self, request):
            cookie_name = settings.REST_AUTH['JWT_AUTH_COOKIE']
    ...
    

    I opened an issue to see if a PR would be needed: https://github.com/iMerica/dj-rest-auth/issues/584

    I hope it helps other people.