2012-06-25 9 views
5

私はpythonでjinja2テンプレートプラットフォームのgoogle appengine用のアプリを書いています。私は自分のサイトでうまく動作するためにOpenIDを取得しており、ユーザーがログインできるようにして、自分のメールアドレス/ IDを右上隅に表示することができます。openidユーザーに追加情報を与える

ユーザーは自分のユーザー名を持ち、サイト訪問やサイトの特定の投稿などの追加のデータを保存できるようにします。

私は、データベースでユーザーとすべてを使ってテーブルを作成する必要があることを知っていますが、これをOpenIDで行う正しい方法は何ですか。誰かが初めてログインしたときに自動的にそのユーザーを作成したいのですが、これを効率的に行う方法がわかりません。私はデータベースのfederated_identityを確認するログイン後にページにリダイレクトすることで管理できると思います。すでに存在する場合はホームページにリダイレクトしますが、そうでなければ新しいユーザーを作成します。

もっと効率的な方法があるので、誰かがログインするたびにデータベースに照会していないか、それともそれほどうまくいかない方法ですか?

答えて

6

あなたはあなた自身のユーザーモデルを作成し、アプリケーションに追加の情報やビジネスロジックを保存する必要があります。あなたがしなければならない余分なusernameと一緒にユニークなもの(例えばfederated_id)を格納することで、nameなど

その特定federated_idは、データストアであり、あなたがする場合のOpenIDでログインした後、あなたがチェックしますその特定のuser_dbを返すか、デフォルト値で新しいものを作成し、新しく作成されたuser_dbを返します。

重要なことは、お客様のご要望には、user_dbエンティティを扱い、users.get_current_user()ではなく、基本的には読み取り専用であるためです。

はここにもユーザーがログインしてNoneそうされている場合、独自のuser_dbエンティティを返しますget_user()機能付きbase handler classを示して完全な例です。ユーザーが初めてログインしようとしている場合は、新しいuser_dbエンティティは、いくつかのデフォルト値(nameusernameemailadminfederated_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) 

この問題には多くの異なるアプローチがありますが、私はこれがアイデアを得る良いスタートだと思う。

+0

今日の午後から試してみるとどうなるのでしょうか – clifgray

+0

この行が何をしているのか説明できますか?user_db_list = User.query(User.federated_id == federated_user.user_id())fetch( 1) – clifgray

+0

@clifgray特定のfederated_idを持つユーザをあなたのモデルから検索しています...結果が空リストでない場合は、勝者があります。otherwiser私たちは1つのエンティティを作成してからそれを返します.. – Lipis

関連する問題