0

Please see this question and answer from 8 months ago. The answer fixed the problem for a while, but today I discovered that login and logout works again separately for each of my websites (domains), in Chrome and in Dolphin. But, everything works as before in Firefox, Edge and Opera. Did something change in those browsers regarding cookies from other domain names and how do I fix it so that login and logout will work simultaneously in both websites?

The users login or logout or sign up to one website, and I want them to login or logout from the other website too, automatically, and it works with Firefox, Edge and Opera. But users of Chrome and Dolphin, currently if they login or logout to one website, it doesn't affect the other website.

The Django view code is:

@csrf_exempt
def set_session(request):
    """
    Cross-domain authentication.
    """
    response = HttpResponse('')
    origin = request.META.get('HTTP_ORIGIN')
    if isinstance(origin, bytes):
        origin = origin.decode()
    netloc = urlparse(origin).netloc
    if isinstance(netloc, bytes):
        netloc = netloc.decode()
    valid_origin = any(netloc.endswith('.' + site.domain) for site in Site.objects.all().order_by("pk"))
    if (not (valid_origin)):
        return response
    if (request.method == 'POST'):
        session_key = request.POST.get('key')
        SessionStore = import_module(django_settings.SESSION_ENGINE).SessionStore
        if ((session_key) and (SessionStore().exists(session_key))):
            # Set session cookie
            request.session = SessionStore(session_key)
            request.session.modified = True
        else:
            # Delete session cookie
            request.session.flush()
    response['Access-Control-Allow-Origin'] = origin
    response['Access-Control-Allow-Credentials'] = 'true'
    return response

And the JavaScript code is:

window.speedy = {};

window.speedy.setSession = function (domain, key) {
    $.ajax({
        url: '//' + domain + '/set-session/',
        method: 'post',
        data: {
            key: key
        },
        xhrFields: {
            withCredentials: true
        }
    });
};

Then there is a JavaScript code that calls this function twice:

speedy.setSession('speedy.net', 'session_key');
speedy.setSession('speedymatch.com', 'session_key');

Where 'session_key' is replaced by the session key of the user.

And Django settings (with Django 3.0.6):

SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = None

CSRF_COOKIE_SECURE = True
CSRF_COOKIE_SAMESITE = 'Strict'

Is there any solution to this problem? I think this is due to recent changes in Chrome and Dolphin browsers.

I checked and I get the following errors from the console:

From Speedy Match From Speedy Net

It looks like related to the following links:

Uri
  • 2,992
  • 8
  • 43
  • 86

1 Answers1

3

A cookie ... was set without the `SameSite` attribute.

Starting July 14 (2020), you should set these 1,2 and upgrade to Django 3.1 3,4 (released Aug 4):

SESSION_COOKIE_SECURE = True
SESSION_COOKIE_SAMESITE = 'None'

Explanation

Before Django 3.1, the samesite attribute is not set if the setting is the None singleton:

if samesite:
    if samesite.lower() not in ('lax', 'strict'):
        raise ValueError('samesite must be "lax" or "strict".')
    self.cookies[key]['samesite'] = samesite

As of Django 3.1, the samesite attribute is set for the 'None' string; still not for None/False:

if samesite:
    if samesite.lower() not in ('lax', 'none', 'strict'):
        raise ValueError('samesite must be "lax", "none", or "strict".')
    self.cookies[key]['samesite'] = samesite

References

  1. Cookies default to SameSite=Lax - Chrome Platform Status
  2. Reject insecure SameSite=None cookies - Chrome Platform Status
  3. Settings | Django documentation | Django #std:setting-SESSION_COOKIE_SAMESITE
  4. Allowed setting SameSite cookies flags to 'None' · Pull Request #11894 · django/django
aaron
  • 39,695
  • 6
  • 46
  • 102
  • Thank you. I created an issue on Django [ https://code.djangoproject.com/ticket/31933 ] and asked to backport. I don't want to upgrade Django before issue https://code.djangoproject.com/ticket/31864 is fixed (at least in September 2020). – Uri Aug 23 '20 at 01:53
  • I'm also worried about incompatible clients. https://www.chromium.org/updates/same-site/incompatible-clients – Uri Aug 23 '20 at 02:37
  • Anyway I expect to upgrade Django to 3.1.* only around October 2020. I hope they will reconsider their decision and will agree to backport it to Django <= 3.0. – Uri Aug 23 '20 at 02:38
  • I think I can accept this answer if it works in production. I'm going to use a forked version of Django (`-e git://github.com/speedy-net/django.git@3.0.9a#egg=django`). Will it work for most users? What do you recommend to do with users of incompatible clients? – Uri Aug 23 '20 at 10:49
  • I did it and it works with Chrome in production (with the fork I created). But it doesn't work with Dolphin and Chrome on my mobile phone (Chrome also didn't work before). But it does solve the problem with Chrome on desktops. – Uri Aug 23 '20 at 13:40
  • I also noticed that this feature (third-party cookies) is disabled in incognito mode in Chrome (by default). – Uri Aug 23 '20 at 14:42