Users Python API 概要
App Engineのアプリケーションでは
- Google アカウント
- APP Engine のドメインで発行したアカウント
のいずれかをつかって認証ができます。
アプリケーションは現在のユーザーがサインインしているかどうかを識別し、専用のログインページもしくは、Googleアカウントの認証を用いている場合にはGoogleアカウントの作成へリダイレクトさせることができます。
ユーザーがアプリケーションにサインインしている間は、App EngineはユーサーIDだけでなく、メールアドレスにもアクセスできます。Appは現在ログインしているユーザーが管理者かどうかを識別し、管理者のみのツールへのアクセスを容易にします。
User authentication in Python
下記の例では Appにサインインしたユーザーに個別のメッセージを表示し、サインアウトのリンクを表示します。サインインしていないユーザーにはGoogleアカウントのサインインページのリンクを提供します。
from google.appengine.api import users
import webapp2
class MyHandler(webapp2.RequestHandler):
def get(self):
user = users.get_current_user()
if user:
greeting = ('Welcome, %s! (<a href="%s">sign out</a>)' %
(user.nickname(), users.create_logout_url('/')))
else:
greeting = ('<a href="%s">Sign in or register</a>.' %
users.create_login_url('/'))
self.response.out.write('<html><body>%s</body></html>' % greeting)
app.yamlによる管理者に限定したアクセス
app.yamlによって、アクセスするためにログインを必須とするページの設定をすることができます。ユーザーがサインインした状態でなく、アクセスしたページがサインインが必須に設定されているURLの場合はApp Engine は専用のサインインページにリダイレクトし、サインインまたは登録が済んだ後に、ユーザーをもとのURLに戻します。
アプリケーションの管理者として登録されているユーザーを必須にすることも設定で制御することができます。別の認証システムを作る必要がないので、サイトに管理者専用の部分を作ることが容易になります。
参照:Configuring a Python App: Requiring Login or Administrator Status.
https://cloud.google.com/appengine/docs/python/config/appconfig#Python_app_yaml_Requiring_login_or_administrator_status
Authentication options
アプリケーションでは
- Google アカウント
- APP Engine のドメインで発行したアカウント
のいずれかをつかって認証をすることができます。
Choosing an authentication option
APPをつくった後に、使用したい認証オプションを選ぶことができます。デフォルトではGoogleアカウント認証になっています。
そのほかの認証方法を選ぶ場合は、プロジェクトのGoogle Cloud Platform Consoleから[Edit]をクリックします。 Google authentication ドロップダウンメニューから使いたい認証方法を選択し、[save]をクリックしてください。
Signing in and out
Users APIのメソッドを使ってサインインページのURLを取得できますので、Appではユーサーが認証に仏要なページにアクセスしたとき、URLリンクを表示またはHTTPリダイレクトします。
ユーザーのサインインページに表示するアプリケーション名は、アプリケーションに登録されているものが使用されます。Google Cloud Platform Console Projectページからプロジェクトの名前の鉛筆マークをクリックして編集することができます。
一度サインインまたはGoogleアカウントを作成すると、ユーザーはアプリケーションへリダイレクトされます。リダイレクト先は、APIでサインインURLを取得したときに渡したURLになります。
Users API はサインアウトのURLを生成するメソッドがあります。サインアウトURLはアプリケーションからそのユーザーの認証を外して、なにも表示せずに指定したアプリケーションのURLへリダイレクトします。
メールアドレスとパスワードを入力していない、サインインする意図のないユーザーは、他のアプリケーションにGoogleアカウントでサインインしていても、ほかのアプリケーションにサインインされません。
Accessing account information
アプリケーションはサインインしているユーザーのメールアドレスにリクエスト毎にアクセスできます。メールアドレスを変更したとしてもアカウントにたいしてユニークであるユーザー識別子にもアクセスすることができます。
アプリケーションは現在のユーザーが管理者または開発者であるかどうか判別できます。この点を用いて、他のユーザーを自身で認証しなくてもアプリの管理機能を作成することができます。 Go, Java, PHP と Python APIsを使って管理URLの設定が容易にできるようになっています。
Note:すべてのAppEngineのアプリケーションに対し、ユーザーIDは同一になっています。URLのパラメータに含まれるといったように、ユーザーIDが公開される場合はハッシュ化するなど、わからないように一手間くわえる必要があります。そのままのIDがあるアプリで他のユーザーにわかってしまった場合には、そのIDをつかって、ほかのアプリにサインインさせて、メールアドレスを入手することができてしまいます。
Users and the Datastore
Users APIサービスでは現在のユーザーの情報をUserオブジェクトとして返却します。ユーザーIDとメールアドレスが一緒なので、UserオブジェクトをDatastoreに保存しないことを推奨します。メールアドレスは変更されることがあり、保存したときと同じかどうかは保証されません。ユーザーIDは固定的な値なので、こちらを使うようにしてください。
Google accounts and the development server
開発サーバーではダミーのサインイン画面で Googleアカウントのシミュレートができます。URLをUsers APIから取得すると、APIはメールアドレスのみでパスワードを入力しない入力画面の開発サーバーURLを返します。ここではどのようなメールアドレスを入力しても、そのアドレスのアカウントでサインインしたように動作します。
ダミーのサインイン画面は、管理者としてアクセスするかどうかのチェックボックスも表示しています。このチェックボックスをオンにすると、管理者としてサインインしたときのように動作します。
同様に、UsersAPIではダミーのサインアウトも取得できます。
開発サーバーでのユニークユーザー識別子はメールアドレスを元に計算されています。2つのメールアドレスは常に2つのユニークユーザーとなります。
About OpenID
OpenID は非推奨です
User Object
get_current_user()
メソッドでサインインしているユーザーの情報が取得できます
from google.appengine.api import users
user = users.get_current_user()
if not user:
# The user is not signed in.
else:
print "Hello, %s!" % user.nickname()
メールアドレスから生成
user = users.User("Albert.Johnson@example.com")
federated_identity がある場合
user = users.User(federated_identity="http://example.com/id/ajohnson")
有効なGoogleアカウントのメールアドレスでなくともオブジェクトは生成されますが、本当のGoogleアカウントとしてではありません。Usersオブジェクトが保存された後に、メールアドレスが変更された場合も同じです。あるときに作成されたUserオブジェクトが現在のユーザーと一致するかは保証されません。
Using User Values With the Datastore
User ID は固定なので、データストアにキーとして保存できます。
下記の例では、現在のユーザと以前のユーザーと比べています。
from google.appengine.api import users
from google.appengine.ext import ndb
class UserPrefs(ndb.Model):
userid = ndb.StringProperty()
user = users.get_current_user()
if user:
q = ndb.gql("SELECT * FROM UserPrefs WHERE userid = :1", user.user_id())
userprefs = q.get()