Facebook OAuth:自定义callback_uri参数


74

我想为我的Facebook OAuth2集成提供一个动态重定向URL。例如,如果我的重定向URL在我的Facebook应用程序中是:

http://www.mysite.com/oauth_callback?foo=bar

我希望特定请求的重定向URL像这样,以便在服务器上,我具有有关如何处理身份验证代码的上下文:

http://www.mysite.com/oauth_callback?foo=bar&user=6234

提交授权对话框后,我的重定向被调用,并且我返回了身份验证代码,但是当我尝试获取访问令牌时,我从Facebook返回了OAuthException错误。我的请求如下所示(为清楚起见添加了换行符):

https://graph.facebook.com/oauth/access_token
    ?client_id = MY_CLIENT_ID
    &redirect_uri = http%3A%2F%2Fwww.mysite.com%2Foauth_callback%3Ffoo%3Dbar%26user%3D6234
    &client_secret = MY_SECRET
    &code = RECEIVED_CODE

我所有的参数都是URL编码的,并且代码看起来有效,所以我唯一的猜测是问题参数是我的redirect_uri。我尝试将redirect_uri以下所有设置都无济于事:

  1. 请求到我的网站的实际URL
  2. 到我的网站的请求的网址,减去code参数
  3. 我的Facebook应用程序配置中指定的URL

是否支持自定义重定向URI参数?如果是这样,我是否正确指定了它们?如果没有,我是否会被迫设置cookie,或者是否有一些更好的模式来为我的网站提供上下文?

Answers:


100

我想出了答案。您可以state在请求中添加一个参数,而不是向重定向URL添加其他参数https://www.facebook.com/dialog/oauth

https://www.facebook.com/dialog/oauth
    ?client_id = MY_CLIENT_ID
    &scope = MY_SCOPE
    &redirect_uri = http%3A%2F%2Fwww.mysite.com%2Foauth_callback%3Ffoo%3Dbar
    &state = 6234

然后将该状态参数传递到回调URL。


但是状态参数只能包含数字字符,不是吗?
superscral

8
不可以,它可以包含任何任意数据。在撰写本文时,我正在将整个JSON对象放入该参数(当然是URL编码)。
Jacob

12
该状态用于随机不可猜测的散列,以防止CSRF。有办法解决吗?
CMCDragonkai 2013年

2
有趣的是,他们的文档没有提及它最初是针对CSRF的。但是,这并没有改变以下事实:它似乎是他们提供的传递任意数据的唯一方法。我想您可以将state参数设置为同时包含现时和状态数据的JSON结构,或者将现时仅用于查找其余信息。
雅各布

好答案..!我把这个用于facebook。但是我们如何对Twitter做同样的事情。它不起作用:(
azzaxp 2013年

12

如果因任何原因,你不能使用选项雅各布建议,因为它是我的情况下,可以进行urlencoderedirect_uri传递之前的参数,它会工作,即使像一个完整的查询字符串foo=bar&morefoo=morebar在里面。


6
你能举个例子吗?
CMCDragonkai 2013年

它曾经以这种方式为我工作,然后停下来;现在,“共享”state用于XSRF保护以及我自己的ID的参数对我来说就是解决方案。
Erik Kaplun'1

这不再起作用了,至少在我看来这是行不通的。从身份验证重定向时,它仅返回第一个查询字符串参数。
里脊

3

本教程之后,我试图针对API v2.9实现Facebook登录工作流。我尝试了上述解决方案。Manuel的回答是正确的,但我观察到的是不需要url编码。另外,您只能传递一个参数。只考虑第一个查询参数,其余的将被忽略。这是一个例子

  1. 通过请求代码 https://www.facebook.com/v2.9/dialog/oauth?client_id={app-id}&redirect_uri=http://{url}/login-redirect?myExtraParameter={some-value}

  2. 您会收到网址的回调。它看起来像http://{url}/login-redirect?code={code-from-facebook}&myExtraParameter={value-passed-in-step-1}。请注意,facebook将使用进行回调myExtraParameter。您可以myExtraParameter从回调URL中提取的值。

  3. 然后,您可以使用 https://graph.facebook.com/v2.9/oauth/access_token?client_id={app-id}&client_secret={app-secret}&code={code-from-facebook}&redirect_uri=http://{url}/login-redirect?myExtraParameter={value-extracted-in-step-2}

第一个查询参数之后在步骤1中传递的其他参数将被忽略。另外,还要确保不包括在查询参数的任何无效字符(请参阅了解更多信息)。


也许Facebook服务器是宽容的,但是您绝对应该使用URL编码redirect_uri?URL和&s中都必须包含未编码的秒数,这是无效的,因为这会使参数列表不明确。如果您使用网址编码,则不必担心避免在参数中使用“无效字符”。您的其他参数可能由于缺少编码而被“忽略” &(如何区分它是参数分隔符还是callback_uri其他参数?)
Jacob

@mert我已经在Facebook登录产品的“有效OAuth重定向URI”中添加了我的回调URL,Client OAuth Settings而没有添加其他参数。就我而言,它不起作用URL Blocked: This redirect failed because the redirect URI is not whitelisted in the app’s Client OAuth Settings. Make sure Client and Web OAuth Login are on and add all your app domains as Valid OAuth Redirect URIs.
Puneet

0

您应该state使用登录助手来设置自定义参数,如下所示:

use Facebook\Facebook;
use Illuminate\Support\Str;

$fb = new Facebook([
    'app_id' => env('FB_APP_ID'),
    'app_secret' => env('FB_APP_SECRET'),
    'default_graph_version' => env('FB_APP_VER'),
]);

$helper = $fb->getRedirectLoginHelper();

$permissions = [
    'public_profile',
    'user_link',
    'email',
    'read_insights',
    'pages_show_list',
    'instagram_basic',
    'instagram_manage_insights',
    'manage_pages'
];

$random = Str::random(20);

$OAuth2Client = $fb->getOAuth2Client();

$redirectLoginHelper = $fb->getRedirectLoginHelper();

$persistentDataHandler = $redirectLoginHelper->getPersistentDataHandler();

$persistentDataHandler->set('state', $random);

$loginUrl = $OAuth2Client->getAuthorizationUrl(
        url('/') . '/auth/facebook',
        $random,
        $permissions
    );

0

嘿,如果您使用的是官方的Facebook php skd,则可以这样设置自定义state参数

$helper = $fb->getRedirectLoginHelper();
$helper->getPersistentDataHandler()->set('state',"any_data");
$url = $helper->getLoginUrl($callback_url, $fb_permissions_array);

-1

你最好指定唯一的回调每个OAuth的提供商,/oauth/facebook/oauth/twitter等。

如果您确实希望同一文件响应所有oAuth请求,则可以将其包含在单个文件中,或者设置一个路径,该路径将使用.htaccess重定向或类似方法在您的服务器上调用同一文件:/oauth/*>oauth_callback.ext

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.