Consistent user authorization across url with/without www - django

I need to clarify a fundamental concept (beginner here).
In a Django web app I maintain, I notice that if one logs in via going to example.com, they remain logged out on www.example.com (and can then go on to create a clone account).
1) Why does this happen?
2) What's the standard practice to iron out this issue? I.e., give one consistent experience across www and no-www.
In case the answer is as basic as just a redirection, I could use some pointers and an illustrative example there too - I'm using nginx reverse proxy with gunicorn.

1 ) Django cookies do not work for same with a prepended www and non-www domain by default.Django considers it as a different sessions.
2) The PREPEND_WWW setting you can set to redirect your xyz.com to www.xyz.com.
PREPEND_WWW = True
or if you need same cookie to both of the sites you can use session_cookie_domain,
SESSION_COOKIE_DOMAIN = ".yoursite.com"

Related

Redirect domain to .com in django in url.py

I have a website in Django, hosted in Heroku.
I have 2 domains, registered in different places:
mysite.com and mysite.com.br
I don't want to be penalized by Google for having 2 domains with the same website, therefor I would like to redirect everyone who enters mysite.com.br to mysite.com.
I entered in the DNS mysite.com.br(Not hosted anywhere) CNAME mysite.com(hosted in Heroku), which makes the user actually access the Heroku content, but the url keeps the .BR ....
So the Heroku support told me to do the redirection in the application. In this case, what's the best practice to redirect? I would imagine to do that in the url.py, but how can I do that if the "path" doesnt read the domain?
Thanks.
You can't do this in the URLs. I would write some middleware to check the host via request.get_host and redirect if you're not on the canonical one.
In fact it looks like someone has already written this: django-enforce-host.

Mezzanine HOST_THEMES www- subdomain pointing to wrong site

I'm using the Mezzanine Django-based CMS using its Multi-Tenancy ability to serve two sites through the same backend, and have a quirk occurring with respect to the "www" subdomain from one of the sites. At the moment, this is how it's working:
site_1.com -> site_1
www.site_1.com -> site_1
site_2.com -> site_2
www.site_2.com -> site_1
As you can see, the "www" subdomain is going to the wrong site. The HOST_THEMES setting seems to be set correctly, however - like so:
HOST_THEMES = [('www.site_1.com', 'site_1_theme'),
('site_1.com', 'site_1_theme'),
('www.site_2.com', 'site_2_theme'),
('site_2.com', 'site_2_theme')]
Additionally, Admin>Settings>Sites is set like so:
site_1.com
site_2.com
(No "www"s are listed, since adding one would add a completely separate site in the admin for content). What is the proper way to handle www subdomains here? Why would it properly handle the raw domain, yet not the www?
Thank you.
Redirect the www sites to the non-www sites (or vice-versa), in your nginx/apache conf.

Avoiding double caching of items available from different URIs using Varnish

In the Varnish Cache wiki it states an example of how to regsub to avoid caching request to www.example.com and example.com separately. The example from https://www.varnish-cache.org/trac/wiki/RedirectsAndRewrites is:
set req.http.host = regsub(req.http.host, "^www\.example\.com$","example.com");
"Requests to www.example.com and example.com will all go to the backend as "example.com" and end up cached by that string." This means duplicate caching does not occur.
I have multiple sites using the same varnish server (VCL) so am looking to replace "example.com" with a statement that will work on multiple URLs. eg:
www.example1.co.uk > example1.co.uk
www.example2.com > example2.com
What would be the appropriate regex (if that is the correct term) for this?
There are multiple separate domains (different sites with different content on different domains) using this VCL I am hoping to avoid having to alter the vcl when new sites are added/removed. Therefore a generic solution is what I am after, something that can be applied to any domain to remove the possibility of a duplicate with/without the WWW alias being store/served by Varnish. (Having trouble phrasing this, hope it is clearer!!)
I am aware that redirecting can be done outside of varnish, in Apache etc, but not looking for that as a solution.
set req.http.host = regsub(req.http.host,
"^www\.(.*)$",
"\1");
This will strip www off any domain. (I do feel reluctant to give you this answer, as it goes against my religion)
You might get penalized by search engines for serving the same content on multiple URLs, but SEO is a different topic.
Instead of what Chris suggested, you can just remove the www part:
set req.http.host = regsub(req.http.host, "^www\.", "");
Should be a teeny tiny bit faster, too

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.