Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

facebook login server-side using golang not working

Tags:

facebook

go

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.

like image 699
Anonymouse Avatar asked Feb 19 '23 03:02

Anonymouse


2 Answers

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:

  1. Make sure you're not expecting vanilla goauth2 to handle Facebook OAuth2 responses, as it doesn't (yet).
  2. If you're using App Engine, create any http clients via urlfetch.Client().
  3. Try your authentication request outside of your go code.
  4. 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.

like image 180
Rich Churcher Avatar answered Feb 26 '23 20:02

Rich Churcher


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.

like image 27
rputikar Avatar answered Feb 26 '23 21:02

rputikar