Google App Engine では、Google インフラ上のいくつかの便利なサービスを使用できます。 そのようなサービスの一つにUsers サービスがあります。これを使うと、あなたのアプリケーションと Google ユーザーアカウントを統合することができます。 Users サービスでは、ユーザーは既にログインしている Google アカウントをアプリケーションで使用できます。
Users サービスを使用すると、このアプリケーションでの挨拶文のパーソナライズが簡単にできます。
今回もmyapp/hello.go
を編集し、中身を以下のように書き換えます:
package hello import ( "fmt" "net/http" "appengine" "appengine/user" ) func init() { http.HandleFunc("/", handler) } func handler(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) u := user.Current(c) if u == nil { url, err := user.LoginURL(c, r.URL.String()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Location", url) w.WriteHeader(http.StatusFound) return } fmt.Fprintf(w, "Hello, %v!", u) }
ブラウザー上でページを再読み込みしてください。
ローカルデベロップメントサーバを動作させている時、あなたのアプリケーションはユーザーtest@example.com
を表示します。
これは、ローカルデベロップメントサーバが動作している時のみ表示されるユーザー名です。
しかし、アプリケーションがApp Engine上で動作している場合はユーザーはGoogle アカウントのログインベージに送られ、ログインもしくはアカウントの作成に成功するとアプリケーションに送り返されます。
それでは、新しく追加したコードを詳しく見てみましょう:
// Create a new context. c := appengine.NewContext(r)
このappengine.NewContext
関数は現在のリクエストと関連するappengine.Context
値を返します。
これは、App Engine サービスと通信するためにGo App Engine SDKの多くの関数で使用される不定値です。
// Get the current user. u := user.Current(c)
ユーザーが既にあなたのアプリケーションにログインしている場合、 user.Current
はそのユーザーのuser.User
値への参照を返します。
ログインしていない場合は、nil
を返します。
if u == nil { url, err := user.LoginURL(c, r.URL.String()) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } w.Header().Set("Location", url) w.WriteHeader(http.StatusFound) return }
ユーザーがログインしていない場合は、Location
ヘッダを設定してHTTPステータスコード302 "Found"を返すことで、
ユーザーのブラウザをGoogle アカウントログイン画面にリダイレクトします。
リダイレクトにはこのページの情報(r.URL.String()
)も含まれているので、 ユーザーがログインしたり新規アカウント登録した後に、Google アカウントログイン側の処理機構はユーザーをアプリケーションのページへ送り返すことができます。
user.LoginURL
関数は、戻り値の第二引数として error
値を返します。
ここでエラーが発生することは少ないですが、可能であればエラーを確認してエラーユーザを表示したほうが良いでしょう
(in this case, with the http.Error
helper).
// Display an output message with user name. fmt.Fprintf(w, "Hello, %v!", u)
ユーザーがログインしている場合は、ユーザーアカウントと関連するを使ってパーソナライズされたメッセージが表示されます。
今回の場合、fmt.Fprintf
関数は *user.User
の String
メソッドを呼んで文字列フォーム内のユーザー名を取得します。
Users APIに関する詳細情報については、 Users リファレンスを参照してください。
注意: ログインユーザーのためだけに表示される特別なパスを作るには、app.yaml
ファイルでlogin: required
ディレクティブを使用してください。
詳細についてはapp.yaml リファレンスを参照してください。
これでアプリケーションは、訪れたユーザーに名前で挨拶できます。それでは、ユーザーがお互いに挨拶できる機能を追加しましょう。