iMerica / dj-rest-auth

Authentication for Django Rest Framework
https://dj-rest-auth.readthedocs.io/en/latest/index.html
MIT License
1.67k stars 313 forks source link

Prevent SessionID cookie from being sent with JWT token HttpOnly Cookies on Login #325

Open ghost opened 2 years ago

ghost commented 2 years ago

Wondering if it is possible to disable the "sessionID" cookie from being sent after the user hits the login endpoint for dj-rest-auth (for my use case this is one of the social login endpoints).

Currently the login endpoint is sending back the following cookies:

I do not want to remove session authentication completely since if a user logs in through admin they should be able to still use their session authentication. I just want to prevent users logging in through dj-rest-auth social (jwt cookie based) login from receiving these cookies (so that they don't have both session and jwt cookie auth on at the same time).

My settings look as follow:

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "corsheaders.middleware.CorsMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": (
        "dj_rest_auth.jwt_auth.JWTCookieAuthentication",
        "rest_framework.authentication.SessionAuthentication",
    ),
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticated",
    ],
}

# dj-rest-auth jwt auth settings
REST_USE_JWT = True
JWT_AUTH_COOKIE = "app-auth-token"
JWT_AUTH_REFRESH_COOKIE = "app-refresh-token"
JWT_AUTH_COOKIE_USE_CSRF = True
JWT_AUTH_HTTPONLY = True
REST_SESSION_LOGIN = False

Sincere apologies if I am misunderstanding something here or not configuring the settings properly, I am still new to this library. I looked through the documentation and didn't find a configuration for this.

SilvioMessi commented 2 years ago

The methods complete_social_login (in dj-rest-auth) and django_login (in allauth) are called (see two links below) causing the session cookie to be set, as per standard djagno login flow.

https://github.com/iMerica/dj-rest-auth/blob/b72a55f86b2667e0fa10070485967f5e42588e3b/dj_rest_auth/registration/serializers.py#L151 https://github.com/pennersr/django-allauth/blob/36dd5a7dad52429143434517c50811927283e0bb/allauth/account/adapter.py#L401

My solution is to have a custom allauth account adapter and set it in my django app settings.

from allauth.account.adapter import DefaultAccountAdapter

class DefaultAccountAdapterCustom(DefaultAccountAdapter):

    def login(self, request, user):
        pass

    def get_login_redirect_url(self, request):
        return None
ACCOUNT_ADAPTER = 'somewhere.in.your.project.DefaultAccountAdapterCustom'
zach-cullen commented 2 years ago

This particular implementation of using the adapter to override login didn't work for me, since it looks like the session is being created before the custom login is called. My solution is to delete the session in custom login method

from allauth.account.adapter import DefaultAccountAdapter

class DefaultAccountAdapterCustom(DefaultAccountAdapter):
  def login(self, request, user):
    del request.session
Aniket-Singla commented 1 year ago

I came accross the same issue, for me I am trying to delete both session and csrf cookie by below code by overriding DefaultAccountAdapter.

    def login(self, request, user):
        # HACK: Django Allauth is Doing a session login which is not required for this case Hence removing this.
        # Authentication will be performed by Dj-rest-auth in the end
        super().login(request, user)
        request.session.flush()
        request.META.update({
            "CSRF_COOKIE_USED": False,
            "CSRF_COOKIE": None,
        })
        request.csrf_cookie_needs_reset = False

I believe it would be better to be handled by dj-rest-auth as sessions / csrf are not expected if we have set SESSION_LOGIN as False. The issue occurs for social Logins.