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,而不是当前标准。)相反,您可以使用goauth2 的这个分支,它允许Facebook 在某些地方使用 URL 查询字符串格式而不是 JSON。

不幸的是,如果您使用的是 App Engine,那么还有另一个问题:您不能使用任何依赖 DefaultClient 的东西,因为 App Engine 要求您使用他们的 urlfetch service创建客户端。我不清楚您是否正在为 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. 确保您不希望 vanilla 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 回答