I managed to ease the problem, so here is the solution, and I hope someone can benefit from it: 1) Google account verification is not performed on the google accounts server for every request of your application. For example: 1.1 the user logs into your application using his gmail account 1.2 the user also moves to gmail.com where they check their email 1.3 they exit gmail 1.4 they remain in your application and can use it fully This means that you you need to take care of ending the session at the end, your Google account will not take care of it.
2) The Python core that I used is the following:
from openid.consumer.consumer import Consumer, \ SUCCESS, CANCEL, FAILURE, SETUP_NEEDED from openid.consumer.discover import DiscoveryFailure from django.utils.encoding import smart_unicode from myapp.common.util.openid import DjangoOpenIDStore def google_signin(request): """ This is the view where the Google account login icon on your site points to, eg http://www.yourdomain.com/google-signin """ consumer = Consumer(request.session, DjangoOpenIDStore())
3) the additional lib that I created and imported above (myapp.common.util.openid) is a merge of several existing Django openID libraries, so desired for these guys:
from django.db import models from django.conf import settings from django.utils.hashcompat import md5_constructor from openid.store.interface import OpenIDStore import openid.store from openid.association import Association as OIDAssociation import time, base64 from myapp.common.db.accounts.models import Association, Nonce class DjangoOpenIDStore(OpenIDStore): """ The Python openid library needs an OpenIDStore subclass to persist data related to OpenID authentications. This one uses our Django models. """ def storeAssociation(self, server_url, association): assoc = Association( server_url = server_url, handle = association.handle, secret = base64.encodestring(association.secret), issued = association.issued, lifetime = association.issued, assoc_type = association.assoc_type ) assoc.save() def getAssociation(self, server_url, handle=None): assocs = [] if handle is not None: assocs = Association.objects.filter( server_url = server_url, handle = handle ) else: assocs = Association.objects.filter( server_url = server_url ) if not assocs: return None associations = [] for assoc in assocs: association = OIDAssociation( assoc.handle, base64.decodestring(assoc.secret), assoc.issued, assoc.lifetime, assoc.assoc_type ) if association.getExpiresIn() == 0: self.removeAssociation(server_url, assoc.handle) else: associations.append((association.issued, association)) if not associations: return None return associations[-1][1] def removeAssociation(self, server_url, handle): assocs = list(Association.objects.filter( server_url = server_url, handle = handle )) assocs_exist = len(assocs) > 0 for assoc in assocs: assoc.delete() return assocs_exist def useNonce(self, server_url, timestamp, salt):
4) and the model that is required to store google account session identifiers and verified endpoints:
class Nonce(models.Model): """ Required for OpenID functionality """ server_url = models.CharField(max_length=255) timestamp = models.IntegerField() salt = models.CharField(max_length=40) def __unicode__(self): return u"Nonce: %s for %s" % (self.salt, self.server_url) class Association(models.Model): """ Required for OpenID functionality """ server_url = models.TextField(max_length=2047) handle = models.CharField(max_length=255) secret = models.TextField(max_length=255)
Good luck Rok