ChatGPT解决这个技术问题 Extra ChatGPT

Facebook OAuth:自定义 callback_uri 参数

我想为我的 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 设置为以下所有内容,但无济于事:

对我的站点的请求的实际 URL 对我的站点的请求的 URL,减去代码参数 在我的 Facebook 应用程序配置中指定的 URL

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


J
Jacob

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

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。


但是状态参数只能包含数字字符,不是吗?
不,它可以包含任意数据。在我写这篇文章的时候,我把一个完整的 JSON 对象放在那个参数中(当然是 URL 编码的)。
该状态旨在用于随机不可猜测的哈希以防止 CSRF。有没有办法解决这个问题?
有趣的是,他们的文档没有提到它最初是针对 CSRF 的。然而,这并没有改变这样一个事实,即它似乎是他们传递任意数据的唯一方式。我想你可以让你的状态参数成为一个包含随机数和你的状态数据的 JSON 结构,或者随机数仅用于查找其余信息。
很好的答案..!我把这个用于脸书。但是我们如何为 twitter 做同样的事情。它不工作:(
M
Manuel Pedrera

如果出于任何原因,您无法使用 Jacob 建议的选项,因为这是我的情况,您可以在传递 redirect_uri 参数之前对其进行 urlencode 并且它会起作用,即使使用完整的查询字符串,例如foo=bar&morefoo=morebar 在里面。


你能举个例子吗?
它曾经以这种方式为我工作,然后就停止了;现在“共享”用于 XSRF 保护的 state 参数以及我自己的 ID 是我的解决方案。
这不再起作用了,至少在我的情况下不起作用。从身份验证重定向回来时,它仅返回第一个查询字符串参数。
m
mert

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

通过 https://www.facebook.com/v2.9/dialog/oauth?client_id={app-id}&redirect_uri=http://{url}/login-redirect?myExtraParameter={some-value} 请求代码你会收到你的网址的回调。它看起来像 http://{url}/login-redirect?code={code-from-facebook}&myExtraParameter={value-passed-in-step-1}。请注意,facebook 会使用 myExtraParameter 进行回调。您可以从回调 url 中提取 myExtraParameter 的值。然后您可以使用 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 中传递的附加参数将被忽略。还要确保不要在查询参数中包含任何无效字符(有关详细信息,请参阅 this)。


也许 Facebook 服务器是宽容的,但您绝对应该对 redirect_uri 进行 URL 编码;在 URL 和 & 中包含未编码的第二个 ? 是无效的,因为它会使参数列表不明确。如果您进行 URL 编码,则不必担心在参数中避免“无效字符”。由于缺少编码 &,您的附加参数可能会被“忽略”(否则,它如何区分它是参数分隔符还是 callback_uri 的一部分?)
@mert 我已在 Client OAuth Settings 下 Facebook 登录产品的 `Valid OAuth Redirect URIs` 中添加了我的回调 url,而没有添加其他参数。在我的情况下它不起作用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.
D
Dallas Clark

您最好为每个 oAuth 提供者、/oauth/facebook/oauth/twitter 等指定一个唯一的回调。

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


M
Max

您应该使用登录助手设置您的自定义 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
    );

D
Daniel Masih

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

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

关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅