实现不使用http.Redirect的OAuth2 Facebook登录

huangapple go评论162阅读模式
英文:

Implementing OAuth2 Facebook login without http.Redirect

问题

以下是翻译好的内容:

以下的App Engine处理程序在我可以获取令牌的范围内工作:

func home(w http.ResponseWriter, r *http.Request) {
    c := appengine.NewContext(r)

    oaConfig := map[string]string{
        "ClientID":     "(已编辑)",
        "ClientSecret": "(已编辑)",
        "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
        url := oaConfig["AuthURL"] +
            "?client_id=" + oaConfig["ClientID"] +
            "&redirect_uri=" + oaConfig["RedirectURL"] +
            "&state=SOME_UNIQUE_VALUE"
        http.Redirect(w, r, url, http.StatusFound)
    }

    // 2. 请求Token
    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. 从响应体中读取Token
        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。

英文:

The following App Engine handler works to the extent that I can obtain a token:

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)
}
}
// ...
}

When hooked up to a template, this obtains a token response from Facebook and happily displays it. However, it would be nice not to have to redirect the user to example.com/?state=SOME_UNIQUE_VALUE&code=AQB0iYpAf8nMmX5blahblah#= in order to achieve a login.

Is there a way to use client.Get etc to visit the authorise URL, follow the redirect, obtain the code from the resulting query string and stuff it into a string for use by the handler? Without resorting to Ajax, that is.

答案1

得分: 4

没有,因为用户可能需要输入他们的Facebook登录凭据(如果他们是首次使用者,可能还需要连接到您的应用程序)-如果您在没有向用户显示的情况下从服务器上完成所有操作,这几乎是不可能的。

如果您想在用户已经登录到Facebook的情况下识别他们重新访问您的应用程序-只能在客户端完成。JS SDK的FB.getLoginStatus可以为您完成这个操作-它将识别用户,并同时为他们提供有效的访问令牌。

英文:

> Is there a way to use client.Get etc to visit the authorise URL, follow the redirect, obtain the code from the resulting query string and stuff it into a string for use by the handler?

No, because the user may have to enter their login credentials to Facebook (and maybe connect to your app too, if they are a first time user) – and that can hardly be done, if you do it all from your server without showing it to the user.

If you want to recognize existing users re-visiting your app when they are already logged in to Facebook – that can only be done client-side. FB.getLoginStatus from the JS SDK is able to do that for you – it will recognize the user, and give you a valid access token for them at the same time.

huangapple
  • 本文由 发表于 2012年12月16日 08:17:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/13897425.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定