4

Facebook でサーバー側の認証を行おうとしています。ログイン ダイアログと権限を取得できますが、リダイレクト後、リダイレクト ハンドラで認証「コード」を取得できませんでした。なにか提案を?

FBCfg = &oauth.Config { //setup
    ClientId: appId, ClientSecret: appSecret,
    AuthURL: "https://www.facebook.com/dialog/oauth",
    TokenURL: "https://graph.facebook.com/oauth/access_token",
    RedirectURL: "http://"+domain+"/fedlogin/facebook/redir",
    Scope: "",
}

func FBHandleAuth(w http.ResponseWriter, r *http.Request) {
    url := FBCfg.AuthCodeURL("")
    http.Redirect(w, r, url, http.StatusFound)
}

func FBHandleRedir(w http.ResponseWriter, r *http.Request) {
    code := r.FormValue("code")
    w.Write([]byte(code)) //<-- empty, no code returned.
}

編集: オリジナルの goauth2 最新バージョンを使用しています。

4

2 に答える 2

6

私もこれに時間を費やしてきました。私の最近のかなりばかげた質問のサンプルがあなたに役立つかどうかはわかりませんが、念のためリンクしてください。

私のはgoauth2を使用していないことに注意してください。「ストック」のgoauth2 が Facebook の OAuth2 の実装 (現在の標準とは対照的にドラフト 20 であると私は信じています) では特にうまく機能しないことに気付いているかもしれませんし、気付いていないかもしれません。 JSON ではなく、いくつかの場所で Facebook が URL クエリ文字列形式を使用しているためです。

残念ながら、App Engine を使用している場合、別の問題があります。App Engine では、urlfetch サービスを使用してクライアントを作成する必要があるため、DefaultClient に依存するものは使用できません。あなたが App Engine 向けに書いているかどうかは私にははっきりしないので、問題にならないかもしれません。

おそらく、クエリ文字列が返されているかどうかを確認する必要があります。たとえば、https://graph.facebook.com/oauth/authorize?client_id=123456789&redirect_uri=http://youruri/&state=somestateを使用して手動でテストするとどうなりますか? コード応答を取得しますか? これは、クエリ文字列形式で返されないエラーを検出するのに役立ちます。そのため、気付かない可能性があります...エラーは JSON 応答として返されます。

{
   "error": {
      "message": "Error validating application. Invalid application ID.",
      "type": "OAuthException",
      "code": 101
   }
}

要約すると:

  1. バニラの goauth2 が Facebook OAuth2 応答を処理することを期待していないことを確認してください (まだ)。
  2. App Engine を使用している場合は、urlfetch.Client() を介して http クライアントを作成します。
  3. go コードの外で認証リクエストを試してください。
  4. 後付けとして、r.URL の内容を確認して、ハンドラーがクエリ文字列を含む URL 全体を受信して​​いることを確認してください。

編集: 12 月 16 日の時点で、ポイント 1 について間違っています: goauth2 がFacebook を処理するように更新されました

于 2012-12-20T17:30:58.590 に答える
2

goauth2ソースから

//      // The user will be redirected back to this handler, that takes the
//      // "code" query parameter and Exchanges it for an access token.
//      func handler(w http.ResponseWriter, r *http.Request) {
//              t := &oauth.Transport{Config: config}
//              t.Exchange(r.FormValue("code"))
//      // The Transport now has a valid Token. Create an *http.Client
//      // with which we can make authenticated API requests.
//      c := t.Client()

だからあなたが交換した場合

code := r.FormValue("code")

t := &oauth.Transport{Config: config}
t.Exchange(r.FormValue("code"))
c := t.Client()

認証されたhttpクライアントがあります。

于 2012-12-19T16:52:21.917 に答える