Flask - User logged out when switching to www.* - cookies

I'm encountering a strange behavior, and I'm not really sure if it is framework-related or not.
Anyway, for my Flask project I'm using flask-login to manage user authentication.
I noticed that when I'm logging in from domain.com and then I'm switching to www.domain.com, the user appears to be logged out.
If I'm switching back to domain.com the user appears to be logged in (as expected).
This behavior doesn't go both ways, which means that logging in on www.domain.com will keep me logged in on domain.com too.
I'm not sure if it's an issue with flask-login and how it sets the session cookies or if it's related with how cookies work and so on.
Maybe you could help me out on this one :)

I believe you have to set the domain on the cookie to be .domain.com instead of domain.com for the cookie to be available to all subdomains. See this StackOverflow Question for more details!

You need to include the following line to your config file.
http://flask.pocoo.org/docs/0.12/config/
SESSION_COOKIE_DOMAIN = '.domain.com'

Related

Setting JupyterHub SameSite Cookie Attribute

I have jupyterhub(TLJH) running on my AWS. It is served on my site using an iframe. Since the latest chrome update, the "SameSite" cookie attribute is causing the following issue. The below image shows what I see in the Iframe
Given below is the warning I get in my console:
A cookie associated with a cross-site resource at http://www._____.com/ was set without the SameSite attribute. A future release of Chrome will only deliver cookies with cross-site requests if they are set with SameSite=None and Secure. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.
When I disable the SameSite attribute in chrome://flags/, the iframe loads perfect.
I understand that I need to edit my cookie settings to add {SameSite=None; Secure} somewhere in jupyterhub, but I don't know where.
It looks to me as if you may be able to use the cookie_options setting to add SameSite=None; Secure to the cookies, but I am not 100% sure.
I've raised https://github.com/jupyterhub/jupyterhub/issues/3117 to ask the team to validate.
I could make it work only by making my server map to a subdomain. For example, say the main website which has the Iframe embed is www.mydomain.com, I had to map my Jupyter server to "subdomain.mydomain.com" to make it work.
It is obvious that the above approach was possible because the page I was trying to embed was owned by me. Hoping for an answer for the other scenario!
You can use jupyterhub proxy give your server a domain name like "http:***.mydomain.com" .But this must be subdomain of your site("http://www._____.com/")

Django CSRF_COOKIE_DOMAIN - how to change gracefully

I have a public Django site which uses CSRF protection.
I have not set the CSRF_COOKIE_DOMAIN. My site uses subdomains.
Sometimes, a user ends up having a csrftoken cookie set on .toplevel.com as well as on sub.toplevel.com. This causes problems, as CSRF checking fails if the wrong cookie is used in the check.
I would like to set a CSRF_COOKIE_DOMAIN to .toplevel.com. However, I would also like to delete any csrftoken cookies for any *.toplevel.com subdomains. How would I do this?
If I do not delete the other cookies, I will just end up in the original situation of having two cookies with the same name on different domains, which causes issues.
I had a similar problem. The way I dealt with it is together with CSRF_COOKIE_DOMAIN I also changed the CSRF_COOKIE_NAME, making old "csrftoken" cookies obsolete.

django www vs non-www issue with middleware authentication

I have been having inconsistent behavior with my Django app.
If I login with no www, and then prepend www, it's not authenticated, and all the combinations thereof. (www.mydomain.com and mydomain.com like different sites in terms of auth)
If the authentication code is important, I wrote a middleware based on the tutorial here: http://onecreativeblog.com/post/59051248/django-login-required-middleware
So far I have fixed the issue forcing the appending of www, using PREPEND_WWW = True, but I would still like to understand the issue;)
Does anyone have an idea of what may be going on?
Thanks in advance!
What Zaha Zorg said: Cookies from Django won't work for both a prepended www and non-www domain by default.
However, the deeper issue here is that you're allowing both www and non-www domains of your site to serve identical content. Besides the obvious SEO consequences of having traffic split between the two, you run into issues like these. The proper way to handle this is to redirect all traffic from one to the other (whichever you prefer). The PREPEND_WWW setting you found works perfectly for this. For the opposite (forcing all traffic to non-www), it's recommended to just do a re-write at the server configuration level, such as Apache or Nginx.
You need to look at https://docs.djangoproject.com/en/dev/ref/settings/?from=olddocs#session-cookie-domain
SESSION_COOKIE_DOMAIN
Default: None
The domain to use for session cookies. Set this to a string such as ".lawrence.com" for cross-domain cookies, or use None for a standard domain cookie. See the How to use sessions.
Could it be that cookies depend on the hostname of the server ? This could explain why both domain names are considered different.

django: Is it possible to log a user into a subdomain, from another domain?

The thing is. I have one django app serving different sites.
site1.myapp.com
site2.myapp.com
The users login via a 3rd party SSO system which is then redirected(inkl. a valdiation POST) to https://myapp.com/auth/
However. since my users all belong to only 1 "site" i would like myapp.com/auth/
to log the user into the relevant site, ex. site1.myapp.com or site2.myapp.com and then redirect them to that siteā€¦
Is this at all possible?? or should i go about this in a totally different way? :)
I should mention that when it comes to the general usage of the app I have subdomain middleware to ensure that the users always only visit the subdomain(and data) that their account is valid for.
The reason I want to use subdomains is to make it simple for the users to remember their account url, while maintaining the pros of having to maintain just one django app.
thanks. hope you can help :)
kind regards.
pete
I know this question is old, but since Google brought me here I'll add these links
This answer touches on (A) authentication across subdomains and (B) detecting which subdomain is in use to potentially redirect the user
A.1. If you want to allow all (wildcard) subdomains
*.myapp.com, this is achieved by adding one line to settings.py:
SESSION_COOKIE_DOMAIN=".myapp.com"
Detailed here (SO, 2009), here (SO, 2010) and in Django docs
Note: login now won't work on localhost, so you have two choices if
you need to log in and out on localhost:
1: comment out that line in settings.py, or
2: amend your /etc/hosts file to include the following:
127.0.0.1 localhost
127.0.0.1 dev.myapp.com
Now you can visit dev.myapp.com in your browser, and it'll actually be talking to 127.0.0.1, not your live
website. (Now, across dev.myapp.com, site1.myapp.com,
site2.myapp.com and myapp.com, if you log in/out of one, you'll be
logged in/out of them all.)
A.2. If you want to allow cross-authentication between just those two subdomains, i.e., they won't be logged into site3.myapp.com, then it gets a bit more complicated
B. To view the subdomain being used
There are fancier packages to manage subdomains in django, but you could just look crudely at request.META['HTTP_HOST']:
try:
http_host = request.META['HTTP_HOST']
# alternative: http_host = request.get_host()
except KeyError:
http_host = None
print "Can't find HTTP_HOST"
if http_host and '.myapp.com' in http_host:
subdomain = http_host.split('.myapp.com')[0]
else:
subdomain = ''
Then check if you're happy with the request.user using this subdomain.
Use something like HttpResponseRedirect to send them to a different subdomain if you like. If you've done A.1 or A.2 above, in your app's eyes, they're the same user (already logged in) in the new subdomain.myapp.com after being redirected (they don't have to log in again).
Example: if a user creates an account with ireland.myapp.com and you want to keep them always on that site, then when they try to visit usa.myapp.com, they'll still be logged in, you can identify them and send them back to ireland.myapp.com (fictitious example, not a metaphor for immigration!)
In Django you have the notion of sites. You can create your own log in view. If it's not enough, you can create your own authentification backend.

Django SESSION_COOKIE_DOMAIN

I'm seeing something mysterious with the SESSION_COOKIE_DOMAIN setting in django.
Normally, when I have this set to ".mydomain.net" it works fine. But occasionally cookies don't seem to be being set, because when I log in, I'm not remembered in the session and I become AnonymousUser when I get to the next page.
In these circumstances, if, I change my settings file so that SESSION_COOKIE_DOMAIN is now None or "", then the site behaviour returns to normal. If I change SESSION_COOKIE_DOMAIN back to mydomain, the problem returns.
Any ideas? Is this likely to be a silent failure in the settings? Or could it be something to do with my server configuration? Or the machine I'm accessing the site from?
In all likelihood, you are ending up with multiple sessionid cookies being sent. If you have a sessionid cookie with domain 'example.com' and another cookie with domain '.example.com', Django will test only one of those sessionid values. I am unsure of how Django decides which sessionid value to test for validity.
Check your cookies in your browser (in FF, Tools -> Options -> Privacy -> Something about cookies) and see if they are correctly set. Search for your domain, and see if you have the sessionid cookie is set.
It might be a browser issue as Paul suggests. However, I'd be tempted to do some HTTP analysis with Firebug or Live HTTP Headers in Firefox. Is it trying to set the cookie correctly?