I have a shopify app built in Django that was working fine up until recently. The sessions are not persisting across each request and as a result an exception is being raised because the session for that given key that was set in the previous request does not exist.
Trying the app endpoints outside of Shopify works fine, the sessions persist perfectly between requests so it definitely is an issue within Shopify.
Looking at the sessions table in our database we see multiple sessionkeys with the same data, this indicates another session is being created per request. How do we persist sessions across requests in an iframe?
2
Answers
The version of Django being used was 2.1 which now includes a new feature which helps prevent CSRF attacks. According to the docs the new SESSION_COOKIE_SAMESITE defaults to a value of 'Lax' which is a middle ground between 'Strict' and None.
This feature obviously works well for standalone Django apps but causes them to break when in an iframe similar to Shopify. Setting SESSION_COOKIE_SAMESITE = None in settings.py resolved the issue.
Your approach is not working anymore. Google is going to ban 3rd party cookies soon while firefox & Safari already did that. New apps are required to implement session token authentication since third-party cookies are not going to work soon.
New apps submitted for app reviews will be tested under Chrome incognito tab, which doesn’t allow third-party cookies by default. Even you add ‘Samesite’, session id is not going to pass through cookies. When it can’t pass through, the browser will retry again so you see multiple sessions created. At first, I thought it was server-side error since it looked like infinite loops from the logs.
Django by default creates a cookie storing sessionid when you call request.session in view functions. This cookie is only created when you use request.session. If you don’t use request.session, the app can load without problems. But it’s almost impossible to not use session at all. Even the sample shopify django app is using session.
I think the possible way is to change the session middleware. With the reply from Shopify developer, I know that we can use the shop (dest) and user (sub) fields from the payload to create a unique id and store your session data based on that id. Just customize the default session middleware, remove request.cookies and use this id as the session key. It should be ok.
Personally, I didn’t change this middleware since the workload is too huge. After finishing session token auth, I found out that sessions can’t persist during tester doing app review. If you can implement App Bridge, session token auth and update the default django session, you can persist session data.
IMO, standalone apps may be a better choice for Python / Django developers. If anyone has an easier way, please let me know. I feel desperate to study all of these without any concrete examples.