7
votes

Dunno if Im missing something but here goes. Im trying to get an access_token for my application so that it can go and look up events for certain public groups on facebook, without requiring a user to be logged in.

Im trying to get an access_token from https://graph.facebook.com/oauth/access_token?client_secret=foobar&client_id=foobar&grant_type=client_credentials&format=json&sdk=ios

This returns a string: access_token=xxxx|ugtqdoWfvvo5_S-Fo2D7_I4rdbc

Thats nice and all, but its no json. Any insights on why the returned string is not json encoded ?

Note: Im using the Facebook ios SDK function like so [_facebook requestWithGraphPath:@"oauth/access_token" andParams:params andHttpMethod:@"POST" andDelegate:self];

6

6 Answers

5
votes

This is a BUG: https://developers.facebook.com/bugs/325262010847554

Facebook's OAuth 2.0 implementation is clearly in violation of the spec: http://tools.ietf.org/html/draft-ietf-oauth-v2-25#section-5.1

I'm using Server-side Web App flow and have the same issue that you describe for the iOS SDK.

2
votes

This is fixed as of v2.3 of the graph api. Specify the version by using endpoint https://graph.facebook.com/v2.4/oauth/access_token.
It's easy to accidentally land on the wrong version of the facebook API docs.

1
votes

Here's a snippet to extract your access token and replace the pipe character with the proper escape...

NSURL *accessTokenURL = [NSURL URLWithString:@"https://graph.facebook.com/oauth/access_token?client_id=XXXXXXXXXXXXX&client_secret=XXXXXXXXXXXXXXXXXXX&grant_type=client_credentials"];
NSString *accessTokenResponse = [NSString stringWithContentsOfURL:accessTokenURL encoding:NSUTF8StringEncoding error:NULL];
if(accessTokenResponse != nil) {
    NSMutableString *accessToken = [NSMutableString stringWithString:[accessTokenResponse substringFromIndex:13]];
    [accessToken replaceOccurrencesOfString:@"|" withString:@"%7C" options:NSLiteralSearch range:NSMakeRange(0, [accessToken length])];
}
0
votes

Follow up.

The way I understand the FB ios SDK is that your delegate function will receive an object such as NSArray or NSDictionnary to work with. Looking into the internals of the FB SDK classes it seems that all response are parsed using the SBJSON parser. If the response is not json than that will fail.

[_facebook requestWithGraphPath:@"261247595170" andDelegate:self]; returns nice json. No problems there.

[_facebook requestWithGraphPath:@"oauth/access_token" andParams:params andHttpMethod:@"POST" andDelegate:self]; String returned. SBJSON parser fails.

This seems to be an inconsistency in the FB graph service.

One could write a special function to handle this problem, but if FB decides to change the format of the string, then all IPhone App would stop working, and need to update. Not cool.

-1
votes

If you're using Facebook SDK, I believe that they return NSArray and NSDictionnary

I might be wrong, but try with an objectForKey:@"access_token"

-1
votes

Any insights on why the returned string is not json encoded ?

Yeah, the access token isn't supposed to be JSON-encoded. And there's arguably little value in JSON-encoding a single string anyway.

Why are you expecting it to be so?

Seems I was misinformed about this. The spec states that application/json is to be used for the response body.