Users Python API 概要 [日本語訳]

#Users Python API 概要
https://cloud.google.com/appengine/docs/python/users/

App Engineのアプリケーションでは

- Google アカウント
- APP　Engine　のドメインで発行したアカウント

のいずれかをつかって認証ができます。


アプリケーションは現在のユーザーがサインインしているかどうかを識別し、専用のログインページもしくは、Googleアカウントの認証を用いている場合にはGoogleアカウントの作成へリダイレクトさせることができます。

ユーザーがアプリケーションにサインインしている間は、App EngineはユーサーIDだけでなく、メールアドレスにもアクセスできます。Appは現在ログインしているユーザーが管理者かどうかを識別し、管理者のみのツールへのアクセスを容易にします。

##User authentication in Python

下記の例では　Appにサインインしたユーザーに個別のメッセージを表示し、サインアウトのリンクを表示します。サインインしていないユーザーにはGoogleアカウントのサインインページのリンクを提供します。

```py:
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アカウント認証になっています。

https://console.cloud.google.com/projectselector/appengine/setting

そのほかの認証方法を選ぶ場合は、プロジェクトの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

https://cloud.google.com/appengine/docs/python/refdocs/google.appengine.api.users#google.appengine.api.users.User

`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()

```