Implement single sign-out for community login 2.0

In order to provide a consistent user experience, we must sign the
user out from the main website if the community site provides a logout
button - else that button will appear not to work...
This commit is contained in:
Magnus Hagander
2011-12-27 19:35:51 +01:00
parent 061e33e9a8
commit 88d0b6148d
4 changed files with 47 additions and 0 deletions

View File

@ -114,3 +114,23 @@ The flow of an authentication in the 2.0 system is fairly simple:
community site redirects to this location. If it's not present, then
the community site will redirect so some default location on the
site.
Logging out
-----------
If the community site implements functionality to log the user out, it
should also send a redirect to the main website to cause a logout from
this site as well. If tihs is not done, it will appear to the user as if
the logout didn't work, since upon next login the user is redirected and
automatically logged in again.
The flow for a logout request is trivial:
#. The community website logs the user out of the local instance, however
that works.
#. The community website redirects the user to
https://www.postgresql.org/account/auth/<id>/logout/ (where the id
number is the same id as during login)
#. The main website will log the user out of the community site
#. The main website redirects the user back to the community website,
at the URL <redirection_url>?s=logout (where redirection_url is the
same URL as when logging in)

View File

@ -6,6 +6,7 @@ urlpatterns = patterns('',
# Community authenticatoin
(r'^auth/(\d+)/$', 'account.views.communityauth'),
(r'^auth/(\d+)/logout/$', 'account.views.communityauth_logout'),
# Profile
(r'^profile/$', 'account.views.profile'),

View File

@ -5,6 +5,7 @@ from django.shortcuts import render_to_response, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.utils.http import int_to_base36
from django.contrib.auth.tokens import default_token_generator
from django.contrib.auth import logout as django_logout
from django.conf import settings
import base64
@ -228,3 +229,16 @@ def communityauth(request, siteid):
base64.b64encode(iv, "-_"),
base64.b64encode(cipher, "-_"),
))
@ssl_required
@csrf_protect
def communityauth_logout(request, siteid):
# Get whatever site the user is trying to log in to.
site = get_object_or_404(CommunityAuthSite, pk=siteid)
if request.user.is_authenticated():
django_logout(request)
# Redirect user back to the specified suburl
return HttpResponseRedirect("%s?s=logout" % site.redirecturl)

View File

@ -18,6 +18,7 @@ from django.http import HttpResponseRedirect
from django.contrib.auth.models import User
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth import login as django_login
from django.contrib.auth import logout as django_logout
from django.conf import settings
import base64
@ -47,9 +48,20 @@ def login(request):
else:
return HttpResponseRedirect(settings.PGAUTH_REDIRECT)
# Handle logout requests by logging out of this site and then
# redirecting to log out from the main site as well.
def logout(request):
if request.user.is_authenticated():
django_logout(request)
return HttpResponseRedirect("%slogout/" % settings.PGAUTH_REDIRECT)
# Receive an authentication response from the main website and try
# to log the user in.
def auth_receive(request):
if request.GET.has_key('s') and request.GET['s'] == "logout":
# This was a logout request
return HttpResponseRedirect('/')
if not request.GET.has_key('i'):
raise Exception("Missing IV")
if not request.GET.has_key('d'):