So I am writing an app in python for google appengine on the jinja2 templating platform. I have gotten OpenID to work just fine on my site and it allows the user to login a
You are right, you have to create your own User model and store the extra information and whatever business logic you have in your application. All you have to do is to store something unique (federated_id
for example) along with the extra username
, name
, etc.
After logging in with the OpenID, you will check if that particular federated_id
is in your datastore and you will return that particular user_db
, or create a new one with default values and return the newly created user_db
.
The important thing is that in your requests you will always deal with your own user_db
entity and not the users.get_current_user()
because this is basically read only and limited.
Here is a full example, that also demonstrates a base handler class with the get_user()
function that will return your own user_db
entity if the user is logged in and None
otherwise. If the user is going to login for the first time, a new user_db entity is created with some default values (name
, username
, email
, admin
, federated_id
):
from google.appengine.api import users
from google.appengine.ext import ndb
import webapp2
class User(ndb.Model):
name = ndb.StringProperty(required=True)
username = ndb.StringProperty(required=True)
email = ndb.StringProperty()
federated_id = ndb.StringProperty()
admin = ndb.BooleanProperty()
class BaseHandler(webapp2.RequestHandler):
def get_user_db(self):
federated_user = users.get_current_user()
if not federated_user:
return None
user_db_qry = User.query(User.federated_id == federated_user.user_id())
user_db_list = user_db_qry.fetch(1)
#If that returns non empty list, then return the first element which is the user_db
if user_db_list:
return user_db_list[0]
#Otherwise create a new user_db entity, with default values and return
user_db = User(
name=federated_user.nickname().title(),
username=federated_user.nickname(),
email=federated_user.email(),
federated_id=federated_user.user_id(),
admin=users.is_current_user_admin(),
)
user_db.put()
return user_db
class MainHandler(BaseHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/html'
if self.get_user_db():
self.response.out.write('Hello, %s!</br>' % self.get_user_db().name)
self.response.out.write('<a href="%s">Logout</a>' % (users.create_logout_url(self.request.uri)))
else:
self.response.out.write('Hello, stranger!<br>')
self.response.out.write('<a href="%s">Login</a>' % (users.create_login_url(self.request.uri)))
app = webapp2.WSGIApplication([('/', MainHandler)],
debug=True)
There are many different approaches to this problem, but I think this is a good start to get the idea.