英文:
facebook login server-side using golang not working
问题
我正在尝试使用Facebook进行服务器端身份验证,我可以进入登录对话框和权限页面,但在重定向处理程序中没有收到身份验证的“code”。有什么建议吗?
FBCfg = &oauth.Config { //设置
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)) //<-- 空的,没有返回code。
}
编辑:我正在使用原始的goauth2最新版本。
英文:
I'm trying to do server-side auth with facebook, i can get to login dialog and permission, but after redirect i didn't get the auth 'code' in redirect handler. any suggestion?
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.
}
Edit: I'm using original goauth2 latest version.
答案1
得分: 6
我也花了一些时间在这上面。我不知道我在最近的一个相当愚蠢的问题中的示例是否对你有用,但还是给你提供链接。
你会注意到我的示例没有使用goauth2。你可能知道也可能不知道,goauth2的“原版”在与Facebook的OAuth2实现(我相信是草案20,而不是当前的标准)一起使用时效果不是特别好。相反,你可以使用这个goauth2的分支,它允许在某些地方使用URL查询字符串格式而不是JSON。
不幸的是,如果你正在使用App Engine,还有一个问题:你不能使用依赖于DefaultClient的任何东西,因为App Engine要求你使用它们的urlfetch服务创建客户端。我不清楚你是否在为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
}
}
所以总结一下:
- 确保你不期望原始的goauth2处理Facebook OAuth2的响应,因为它不会(至少目前不会)。
- 如果你正在使用App Engine,请通过urlfetch.Client()创建任何http客户端。
- 在你的go代码之外尝试进行身份验证请求。
- 作为一个事后的想法,通过检查r.URL中的内容,确保你的处理程序接收到包括查询字符串在内的完整URL。
编辑:截至12月16日,我在第1点上是错误的:goauth2已经更新以处理Facebook。
英文:
I've been spending some time on this as well. I don't know if the sample in my recent rather silly question is of any use to you, but linking just in case.
You will note that mine does not use goauth2. You may or may not be aware that the 'stock' goauth2 does not work especially well with Facebook's implementation of OAuth2 (which I believe is draft 20 as opposed to the current standard.) Instead, you can use this fork of goauth2 which makes allowance for Facebook's use of URL querystring format in some places rather than JSON.
Unfortunately if you're using App Engine there's another gotcha: you can't use anything that relies on DefaultClient, because App Engine requires that you create clients using their urlfetch service. It's not clear to me whether or not you're writing for App Engine so that might not be a problem for you.
You should probably check to see if you're getting any query string returned at all. What happens if you test it manually, for example, with https://graph.facebook.com/oauth/authorize?client_id=123456789&redirect_uri=http://youruri/&state=somestate ? Do you get a code response? This will help you pick up any errors, which are not returned in query string format so you might not notice them... they come as a JSON response:
{
"error": {
"message": "Error validating application. Invalid application ID.",
"type": "OAuthException",
"code": 101
}
}
So in summary:
- Make sure you're not expecting vanilla goauth2 to handle Facebook OAuth2 responses, as it doesn't (yet).
- If you're using App Engine, create any http clients via urlfetch.Client().
- Try your authentication request outside of your go code.
- As an afterthought, make sure your handler is receiving the entire URL including query string by checking what's in r.URL.
Edit: as of Dec 16 I am wrong about point 1: goauth2 has been updated to handle Facebook.
答案2
得分: 2
从goauth2源代码中
// 用户将被重定向回这个处理程序,该处理程序获取“code”查询参数并将其交换为访问令牌。
// func handler(w http.ResponseWriter, r *http.Request) {
// t := &oauth.Transport{Config: config}
// t.Exchange(r.FormValue("code"))
// // Transport现在有一个有效的令牌。创建一个*http.Client
// // 用它来进行身份验证的API请求。
// c := t.Client()
所以如果你将
code := r.FormValue("code")
替换为
t := &oauth.Transport{Config: config}
t.Exchange(r.FormValue("code"))
c := t.Client()
你将拥有一个经过身份验证的http客户端。
英文:
From the goauth2 source
// // 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()
So if you replace
code := r.FormValue("code")
with
t := &oauth.Transport{Config: config}
t.Exchange(r.FormValue("code"))
c := t.Client()
You will have an authenticated http client.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论