give openid users additional information

前端 未结 1 1203
夕颜
夕颜 2021-01-18 08:48

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

相关标签:
1条回答
  • 2021-01-18 09:11

    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.

    0 讨论(0)
提交回复
热议问题