Implementing OAuth2 Facebook login without http.Redirect
facebook-graph-api, go, google-app-engine
Solution
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.
Problem
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.