Closed GoogleCodeExporter closed 9 years ago
Discussion here:
https://groups.google.com/d/msg/google-appengine-go/cx8I23OCuW4/lPSkLKbPOmoJ
Original comment by a...@golang.org
on 11 Jan 2012 at 4:10
The Transport Exchange function expects the body of the Token Exchange Request
to be encoded in JSON format
According to this:
http://developers.facebook.com/docs/authentication/server-side/
it looks like Facebook instead encodes it as an URL encoded string
The Transport Exchange function then predictably fails, as it is trying to
decode an URL encoded string as JSON
The Decoding process of the Exchange function needs to decode as JSON for
Google, but as URL for Facebook
Although I think JSON is the more sensible format, it looks like Facebook is
more in agreeance with the OAuth Specification
in specific, section 5.3 of this document: http://oauth.net/core/1.0/
Original comment by Ryan.C.K...@gmail.com
on 12 Apr 2012 at 11:16
In order to get it to work with Facebook, I changed the "updateToken" function
in my copy to look like this:
func (t *Transport) updateToken(tok *Token, v url.Values) error {
v.Set("client_id", t.ClientId)
v.Set("client_secret", t.ClientSecret)
r, err := (&http.Client{Transport: t.transport()}).PostForm(t.TokenURL, v)
if err != nil {
return err
}
defer r.Body.Close()
if r.StatusCode != 200 {
return errors.New("invalid response: " + r.Status)
}
body := make([]byte,r.ContentLength)
_,err = r.Body.Read(body)
if err != nil {
return err
}
var b struct {
Access string `json:"access_token"`
Refresh string `json:"refresh_token"`
ExpiresIn time.Duration `json:"expires_in"`
}
err = json.Unmarshal(body,&b) //I haven't tested to make sure this still works with Google, so beware
if err != nil {
vals,err := url.ParseQuery(string(body))
if err != nil {
return err
}
b.Access = vals.Get("access_token")
b.Refresh = vals.Get("refresh_token") //for facebook, this will actually be nil, but whatever
expires_in,err := strconv.ParseInt(vals.Get("expires"),10,64)
if err != nil {
return err
}
b.ExpiresIn = time.Duration(expires_in)
}
tok.AccessToken = b.Access
tok.RefreshToken = b.Refresh
if b.ExpiresIn == 0 {
tok.Expiry = time.Time{}
} else {
tok.Expiry = time.Now().Add(b.ExpiresIn * time.Second)
}
return nil
}
I haven't yet taken any time to clean up the code, but I can confirm that it
works with Facebook
Original comment by Ryan.C.K...@gmail.com
on 13 Apr 2012 at 12:36
https://github.com/rif/goauth2 Integrates and improves the above modifications
is tested to work with both facebook and google.
Original comment by feric...@gmail.com
on 9 Dec 2012 at 3:03
https://github.com/traviscline/goauth2/commit/40836f37159ddc4258ef3e380c540cbf0d
342460.diff
Here is a patch that falls back to url.ParseQuery if a syntax error occurs in
the initial position.
Original comment by travis.c...@gmail.com
on 11 Dec 2012 at 6:42
Attachments:
Maybe Alexander's approach on issue #11 is better.
Original comment by travis.c...@gmail.com
on 11 Dec 2012 at 6:53
I agree. We're working on a change now.
Original comment by a...@golang.org
on 11 Dec 2012 at 11:18
Original issue reported on code.google.com by
benf...@gmail.com
on 10 Jan 2012 at 3:50