Best way to support multi-login on AppEngine
I'm refactoring for a client an app that should support OpenID, Facebook Connect and custom authentication (email+password). Suppose that i have:
class MyUser(db.Model):
pass
class Item(db.Model):
owner = db.ReferenceProperty(MyUser)
I was thinking to implement different authentication systems this way:
class OpenIDLogin(db.Model): # key_name is User.federated_identity()? User.user_id()?
user = db.ReferenceProperty(MyUser)
class FacebookLogin(db.Model): # key_name is Facebook uid
user = db.ReferenceProperty(MyUser)
class CustomLogin(db.Model): # key_name is the user email
user = db.ReferenceProperty(MyUser)
password = db.StringProperty()
Is there a better solution? There is already an answer here but i can't understand if that's the right solution for me. I've alrea开发者_如何学Gody developed an app using the Users API and another one using Facebook Connect in the past, so i know how to deal with the both, the problem is to wire them together. Switching to another framework isn't an option unfortunately.
I would take a close look at tipfy and its Authentication extension.*
They have implemented a Universal User model that can be used with App Engine's default users API, own auth or third party authentication methods (OpenId, OAuth etc).
Here is the documentation, look for MultiAuthMixin section.
*good programmers write good code; great programmers steal great code
First i used something like:
key_name = '%s|%s' % ('facebook', facebook_uid)
and:
key_name = '%s|%s' % ('myapp', email)
It's good and lookup is fast, but it lacks support for multi-provider login (i.e. user wants to be able to login using both google and facebook).
This is my actual solution:
class User(db.Model):
accounts = StringListProperty() # ['facebook|1234', 'google|4321']
email = StringProperty()
password = StringProperty()
Lookup is slower but it's done just once on login, after that i store user.key().id() in session and use that. It's also good because you can link the user to an email/password combo. The downside is that you must enforce uniqueness manually on your keys (email, facebook id, google id etc...).
精彩评论