6

だから私は jinja2 テンプレート プラットフォームで google appengine 用の python でアプリを書いています。私のサイトで OpenID が正常に動作するようになりました。これにより、ユーザーがログインできるようになり、右上隅に電子メール/ID を表示できます。

ここで、ユーザーが独自のユーザー名を持ち、サイトへのアクセスやサイトの領域への特定の投稿など、ユーザーに関する追加データを保存できるようにしたいと考えています。

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

誰かがログインするたびにデータベースにクエリを実行しないようにするためのより効率的な方法はありますか、それともかなりまともな方法ですか?

4

1 に答える 1

6

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

OpenID でログインした後、その特定federated_idがデータストアにあるかどうかを確認し、その特定の を返すuser_dbか、デフォルト値で新しいものを作成して、新しく作成された を返しますuser_db

重要なことは、リクエストでは、基本的に読み取り専用で制限されているためuser_db、 ではなく、常に独自のエンティティを処理することです。users.get_current_user()

これは、ユーザーがログインしている場合とそうでない場合に独自のエンティティを返す関数を含む基本ハンドラー クラスを示す完全な例です。ユーザーが初めてログインする場合、いくつかのデフォルト値 ( 、、、)を使用して新しい user_db エンティティが作成されます。get_user()user_dbNonenameusernameemailadminfederated_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)

この問題にはさまざまなアプローチがありますが、これはアイデアを得るための良い出発点だと思います。

于 2012-06-25T10:28:43.687 に答える