次の App Engine ハンドラは、トークンを取得できる範囲で機能します。
func home(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
oaConfig := map [string]string {
"ClientID": "(redacted)",
"ClientSecret": "(redacted)",
"Scope": "email",
"AuthURL": "https://graph.facebook.com/oauth/authorize",
"TokenURL": "https://graph.facebook.com/oauth/access_token",
"RedirectURL": "http://www.example.com/",
}
code := r.FormValue("code")
if code == "" {
// 1. Code request
url := oaConfig["AuthURL"] +
"?client_id=" + oaConfig["ClientID"] +
"&redirect_uri=" + oaConfig["RedirectURL"] +
"&state=SOME_UNIQUE_VALUE"
http.Redirect(w, r, url, http.StatusFound)
}
// 2. Token request
client := urlfetch.Client(c)
tokenResponse, err := client.PostForm(oaConfig["TokenURL"],
url.Values{
"client_id": {oaConfig["ClientID"]},
"redirect_uri": {oaConfig["RedirectURL"]},
"client_secret": {oaConfig["ClientSecret"]},
"code": {code},
})
if err != nil {
// ...
} else {
// 3. Read token from response body
defer tokenResponse.Body.Close()
body, err := ioutil.ReadAll(tokenResponse.Body)
if err != nil {
// ...
} else {
token := string(body)
}
}
// ...
}
テンプレートに接続すると、これは Facebook からトークン応答を取得し、喜んで表示します。ただし、ログインを行うためにユーザーを example.com/?state=SOME_UNIQUE_VALUE&code=AQB0iYpAf8nMmX5blahblah# =にリダイレクトする必要がないようにするとよいでしょう。
client.Get などを使用して承認 URL にアクセスし、リダイレクトをたどり、結果のクエリ文字列からコードを取得し、ハンドラーが使用する文字列に詰め込む方法はありますか? つまり、Ajax に頼ることはありません。