Good day. I make a site on Django and faced the following task.

There are: 2 independent site-parts with.

Necessary: implement general authorization / authorization through example0.com (also implemented by me). Do something like Google and Youtube. Consider the possibility of placing sites on different domains.

On example0.com - basic information about the user (nickname, name, group)

On example1.com and example2.com - additional data about the user, specific to a particular site, respectively.

At the entrance , if the user has already logged on to one of the sites - automatically log on to the others (if not right - just Permission denide; did not log in - redirect to LogIn on example0.com - if successful, redirect to the entry point)

If 2 tabs are opened with different sites, and LogOut has happened on one, then the second one should also have an "exit".

Are there any recommendations how to implement this? Perhaps advise the ready-made modules that would not write the bike.

  • one
    If the domain was one, and the sites as subdomains, as in CO, it would be possible to play with cookies and sessions. And since you only need to screw up OAuth, the intersite interaction is usually very difficult - FeroxTL
  • @FeroxTL Well, how to implement if on the same domain? If not difficult, with some example. - StSan

1 answer 1

If you have everything on the same domain, and the sites are subdomains (the same as implemented in CO), then let's consistently examine all cases.

By default, cookies are sent only by exact match. To allow subdomains to read each other's cookies, you can add a period before the name of the cookie - this will install it on the entire domain and all subdomains ( .mydomain.com , RFC 2109 ).

However, modern browsers follow the newer RFC 6265 and ignore all the dots at the beginning, which means that all cookies from the main domain are accessible on subdomains. (However, I still advise you to follow 2109)

Therefore, it is enough to set cookies on the subdomain and they will be available on all domains and subdomains:

 Set-Cookie: name=value; domain=.mydomain.com 

Now let's see what we can do in django. We set the following settings:

 # cookie для сессии будут выставляться глобально на все поддомены SESSION_COOKIE_DOMAIN = ".example.com" # название сессионной переменной, чтобы не было конфликтов SESSION_COOKIE_NAME = "anycookiename" # секретный ключ django, его надо просто установить одинаковым для всех сайтов SECRET_KEY="anykey" 

This way you can get authorization on all sites at once - by logging in on one, we get authorization on all the others.

Not exactly what we need. Now you need to play with cookies and sessions. Here you need to understand that our task is to obtain a session in which you can store anything, in which the id of the authorized user is stored (in my opinion, this variable is called _auth_user )

I will give an example from a really working site. The site itself was located on the main domain (example.com), was the authorization center (auth.example.com) and the second site was on a subdomain (new_site.example.com). The databases for these sites were different - on auth.example.com there was a complete database of all registered users, on the other two it was replenished as they were registered on the main ones. When you visit a site on which you are not registered yet, it was possible to determine whether you are registered in the centering house (and, respectively, on another site). A small example - middleware is implemented, which checks whether a user logged on to any of the other sites for each request (in fact, the request was simply proxied with the same cookies) - this is fjLogged cookie (it must be set manually). user_not_registered inserted when the user is not logged anywhere at all. Well, when authorizing on any of the sites with the presence of this user in the database, he also authorized on this site:

 class FJAuthenticationMiddleware(object): def process_view(self, request, view_func, view_args, view_kwargs): if not settings.DEBUG: if not request.user.is_authenticated() and \ 'fjLogged' in request.COOKIES and \ not request.session.get('user_not_registered'): # Белый список имён функций, в которых происходит авторизация, нужно, чтобы не было было зацикливания на этой функции if view_func.__name__ in [ 'auth', 'fj_complete', ]: return None resp = requests.get(cls.ACCOUNT_URL, cookies=request.COOKIES).json() if 'login' in resp and BaseUser.objects.filter(login=resp['login']).exists(): return HttpResponseRedirect(reverse('social:begin', args=[FJOAuth2.name])) else: request.session['user_not_registered'] = True elif request.user.is_authenticated() and 'fjLogged' not in request.COOKIES: return logout(request, next_page=reverse('index')) 

Of the minuses - for each request on this site left a request to the site authorization. This added a decent load. This is a solution to the "forehead" - not the most beautiful, but working.

In general, when all this was developed (about 1.5 years ago), nothing came up from third-party solutions. A quick search now also did not give anything.

From myself I will say that all this is quite difficult to implement.

There is another option to design the structure of the application a little differently, to redefine the authorization system and manipulating the session, to authorize a person on a particular resource - say, on the first user id site, set the _user_auth_site1 session variable, on subsequent ones similarly. To upload user data, configure multiple connections to different database in jango. It all depends on your imagination.

In general, if your websites are completely different and you do not need to immediately register a user everywhere or display any information while using one of the websites, then I advise you to use oauth - there you just have access to the information that you need to request during registration. All of the above gives a lot of pain to all developers, I advise you to think a few times before doing so.

  • FeroxTL, can you give links to good examples and tutorial for outh ?? - StSan
  • @StSan use python-social-auth - FeroxTL