SameSite Cookie with Python/Django and the Embedded App SDK

Solved
Highlighted
Shopify Partner
7 0 2

My embedded app is running on Django 3.0 and I use the embedded app SDK to make sure the pages are embedded in the admin panel.

 

I use the following Django settings for the new Chrome SameSite=None and Secure requirements:

 

SESSION_COOKIE_SAMESITE = None
CSRF_COOKIE_SAMESITE = None
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SESSION_SAVE_EVERY_REQUEST = True

However, when I test this using chrome://flags/ test settings my app doesn't redirect to my app homepage after authenticating. It creates a new session for a shop but in the last step it doesn't redirect to the homepage.


Also, for a lot of cookies in the Chrome Inspect > Application > Cookies only one single cookie shows Secure and SameSite=None, all other cookies are missing SameSite=None and some don't even show the checkmark for Secure.

 

I was wondering if anyone here ran into the same issue and found a solution?

 

1 Like
Highlighted
Shopify Partner
1 1 2

This is an accepted solution.

By setting:

SESSION_COOKIE_SAMESITE = None 

Django ignores it. 

 

It should be:

SESSION_COOKIE_SAMESITE = 'None' # as a string

However this throws an error. Django have fixed this in the development version (3.1) but that isn't due to be released until August. 

 

I wrote some middleware to get around this issue (tested in Django 3.0.3):

from django.utils.deprecation import MiddlewareMixin


class SameSiteMiddleware(MiddlewareMixin):
    def process_response(self, request, response):
        if 'sessionid' in response.cookies:
                response.cookies['sessionid']['samesite'] = 'None'
        if 'csrftoken' in response.cookies:
                response.cookies['csrftoken']['samesite'] = 'None'
        return response

settings.py

MIDDLEWARE = [
    '<app name>.middleware.SameSiteMiddleware', # position it at the top
    ...
]

SESSION_COOKIE_SAMESITE = None
CSRF_COOKIE_SAMESITE = None
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SESSION_SAVE_EVERY_REQUEST = True

 

Hope this helps,

Matt

 

Edit: make sure you delete the existing sessionid cookie in browser when testing.

2 Likes
Highlighted
Shopify Partner
7 0 2

Fantastic! Thanks for your response Matt, I'll try this out.

1 Like
Highlighted
Tourist
11 0 3

This solution didn't work for me in a later version on django, but I did something similar.

I created a middleware:

 

from django.conf import settings
from django.contrib.sessions.middleware import SessionMiddleware

class SessionMiddleware(SessionMiddleware):
def process_response(self, request, response):
response = super(SessionMiddleware, self).process_response(request, response)

if settings.SESSION_COOKIE_NAME in response.cookies:
response.cookies[settings.SESSION_COOKIE_NAME]['samesite'] = 'None'
if settings.CSRF_COOKIE_NAME in response.cookies:
response.cookies[settings.CSRF_COOKIE_NAME]['samesite'] = 'None'

return response

 

Then I replaced the default magento 'django.contrib.sessions.middleware.SessionMiddleware' in settings.py with 'my_app.middleware.SessionMiddleware'

1 Like
Highlighted
Tourist
3 0 0

thank you for your suggestion

 

i did exactly the same in django 2.2 but it dosn't work as expected in facte CSRF_COOKIE_NAME take the value "None " in middleware but the problem is that the GET request is performed before the execution of the middleware :

1 ) samesite<AsgiRequest: GET '/test'> ( print in the view  )
2) SessionMiddleware CSRF_COOKIE_NAME =  None ( print in the middleware )

 

hence the csrftoken cookie keep the default value in the navigator

0 Likes
Highlighted
Tourist
11 0 3

I only tested this on django 3.0.4

I don't know  how it handles on django 2.2

Try to replace with CSRF_COOKIE_NAME "csrftoken" and SESSION_COOKIE_NAME with "sessionid"

1 Like
Highlighted
Tourist
3 0 0

even changing cookies name  dosn't work

i will migrate to Django 3 and try it 

thank you

0 Likes
Highlighted
New Member
2 0 0

Hey,

 

I'm really stuck at this problem, is there anyone who make it work.

 

I'm using Django 3.0.5

 

Thanks.

0 Likes
Highlighted
Tourist
3 0 0

thanks to the previous answers this is what worked for me 

 

1) in your setting.py 

     a) add the samesite parameters 

 

CSRF_COOKIE_SAMESITE = None
CSRF_COOKIE_SECURE = True

    b) add reference to the middleware you will create in step 2

 

 

 

MIDDLEWARE = [
	'myapp.middleware.SameSiteMiddleware',
...
... ]

 

 

2) create the middleware that will override the None value to be " None" 

 

in your app folder ( myapp ) create a file named middleware.py with the followning code :

 

from django.utils.deprecation import MiddlewareMixin

class SameSiteMiddleware(MiddlewareMixin):
    def process_response(self, request, response):

if 'csrftoken' in response.cookies: response.cookies['csrftoken']['samesite'] = 'None' return response

 

don't hesitate to replay if you have a problem or error 

 

0 Likes
Highlighted
New Member
2 0 0

Thank you 

0 Likes