开发者

Facebook canvas authentication: No signed_request parameter after redirect

In my canvas page, I try to authenticate the user the way it is described in http://developers.facebook.com/docs/guides/canvas/, by using essentially this code (example code from developers.facebook.com):

<?php 

 $app_id = "YOUR_APP_ID";

 $canvas_page = "YOUR_CANVAS_PAGE_URL";

 $auth_url = "http://www.facebook.com/dialog/oauth?client_id=" 
        . $app_id . "&redirect_uri=" . urlencode($canvas_page);

 $signed_request = $_REQUEST["signed_request"];

 list($encoded_sig, $payload) =开发者_运维知识库 explode('.', $signed_request, 2); 

 $data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);

 if (empty($data["user_id"])) {
        echo("<script> top.location.href='" . $auth_url . "'</script>");
 } else {
        echo ("Welcome User: " . $data["user_id"]);
 }

?>

The problem is, the first time the user authorizes my canvas application, Facebook doesn't pass a signed_request parameter when redirecting back (as described in the example code), but a code parameter. When accessing the application the second time (already having confirmed the rights), it passes a signed_request parameter as expected.

Why does it pass a code parameter the first time? The documentation doesn't explain when Facebook passes a code / signed_request parameter.


The problem was that for $canvas_page, I used the canvas URL (e.g. mysite.com/canvas) instead of the canvas page URL (e.g. apps.facebook.com/myapp).


I think you need to append "&response_type=token" to your authentication url:

https://www.facebook.com/dialog/oauth?client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&response_type=token

Then you get back something that looks like:

http://apps.facebook.com/APP_NAME/#access_token=YOUR_APP_ID%YADA_YADA_YADA0&expires_in=3948

And you can extract it with some Javascript:

if (window.location.hash.length == 1)
{
       var accessToken = window.location.hash.substring(1);
}


Facebook uses the code parameter to authenticate your application. In the documentation, it states:

*If the user presses Allow, your app is authorized. The OAuth Dialog will redirect (via HTTP 302) the user's browser to the URL you passed in the redirect_uri parameter with an authorization code*

To complete the authorization, you must now take the code parameter and your app secret and pass it to the Graph API token endpoint (paraphrasing the documentation). This will grant you access to the access token. From this point onward, your application will not require the code parameter for this user because they are already authenticated.

Facebook uses the signed_request to share information with your application. The documentation states three scenarios in which it will pass the signed request. These are:

  • A signed_request is passed to Apps on Facebook.com when they are loaded into the Facebook environment
  • A signed_request is passed to any app that has registered an Deauthorized Callback in the Developer App whenever a given user removes the app using the App Dashboard
  • A signed_request is passed to apps that use the Registration Plugin whenever a user successfully registers with their app

So to conclude, the code parameter is only sent to authenticate the application, while the signed_request is utilized to pass information once the application has been authorized.


Saj-and is very correct. I too struggeled with this alot. When setting the redirect_uri to my domain name, I got an infinate redirect loop. When setting the redirect_uri to the facebook app url, I got an error saying the url is not on my domain and so cannot be accessed. It took the "/" at the end to solve this


I had the same problem with my canvas app, I fixed it by simply redirecting to my application's canvas url in the case that there is a code GET request parameter. After that Facebook sends me POST request that contains the signed_request parameter as expected. Here is the Python Django snippet:

if 'code' in request.GET.keys():
    return HttpResponseRedirect(FACEBOOK_CANVAS_URL)

# ...rest of your canvas handling code here


I struggled with this issue (not getting oauth ID in the signed_request and instead get the "code" after user approves the app) for over a week, and this post (and few others posts) helped me get very close to resolving the issue (I was using my apps canvas URL instead of the canvas page url in the redirect URI, and I didn't specify the namespace in the settings).

After making these corrections, I faced a different issue where the app approval page won't show up for a new user and instead facebook throws the message" application has an error etc.. and finally I figured I was missing a / at the end of the canvas page url in my redirect url.. I had it as https://apps.facebook.com/myappname instead of https://apps.facebook.com/myappname/ in the redirect uri. Adding the / at the end resolved the issue and when a new user access my app using https://apps.facebook.com/myappname (if the user is already logged in ) facebook shows the approval page (upon receiving the response from my server) and once the user approves the app, facebook sends the signed-request with the required auth code to my application. Hope this will be useful for anyone else who might encounter the same issue.


Just to clear the confusion about the code parameter.. Facebook will always send this parameter when user allows the application.. however the signed_request parameter is sent using post or some other method.. it is not sent in the url.. You can access it using $_REQUEST['signed_request']


I had a similar problem that was solved when I assigned a namespace to my app, so it would look like apps.facebook.com/myapp and not apps.facebook.com/1234.


I was experiencing the problem you describe with firefox and with third-party cookies disabled.

I enabled third-party cookies and then the signed_request was suddenly available.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜