【问题标题】:Facebook JS SDK Progressive web app issueFacebook JS SDK 渐进式网络应用程序问题
【发布时间】:2017-09-26 13:08:57
【问题描述】:

我有一个使用 Angular 4 构建的 Progressive Web App。

我的问题是从主屏幕应用程序使用时,Facebook 登录对话框不会自动关闭。它在 chrome 浏览器中打开时工作得很好,但是当我从已安装的主屏幕应用程序中使用它时,对话框窗口打开会询问权限,在授予所有权限后对话框变为空白并且不会关闭或重定向回应用程序。

似乎如果我将 manifest.json 中的“显示”更改为“浏览器”它可以工作,但当“显示”处于“独立”时它不起作用。

我已经搜索了所有但没有成功。

谢谢

【问题讨论】:

  • 这方面有什么更新吗?我正在处理同样的问题
  • @GabrielC.Troia 不,我必须将应用程序保持在浏览器模式。我认为它是一个跨域的东西,而 chrome 正在阻止它。所以尝试做一个自定义登录流程。
  • 谢谢。将其保持在浏览器模式下违背了成为 PWA 的目的,不是吗?
  • 是的,肯定可以,但尚未找到有效的解决方案。我已经到处搜索了,没有任何成功。
  • 谢谢。如果我发现了什么,我会及时通知你

标签: facebook angular google-chrome facebook-javascript-sdk progressive-web-apps


【解决方案1】:

当您的应用安装为渐进式网络应用时,Facebook 登录弹出窗口和父窗口(您的应用)无法像在桌面环境中那样进行通信。

在其他情况下您也会遇到这个问题,例如当您的应用使用 Instagram 或 Facebook 等应用内浏览器启动时。

您可以按照另一个答案的建议实施基于服务器的流程。您还可以在客户端实现自定义重定向流。

自定义重定向流程无需弹出窗口即可工作。当您的用户单击“登录”按钮时,他/她将被重定向到 Facebook 登录屏幕。登录后,用户将使用包含验证身份验证成功或失败所需的所有内容的 URL 重定向回您的应用。

Facebook SDK 文档中的“手动构建登录流程”下描述了如何创建自定义重定向流程:

https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow

思路如下:

您将用户引导至 Facebook 登录对话框(不是 FB.login() 启动的弹出窗口),例如当他们点击按钮时:

https://www.facebook.com/v2.11/dialog/oauth?
  client_id={app-id}
  &redirect_uri={redirect-uri}
  &response_type=token
  &state={state-param}

如果用户成功授予您的应用必要的权限,他/她将被重定向回您的应用(位置由{redirect-url} 确定):

{redirect-uri}?code=<facebook-code>&state={state}#_=_

然后你的应用需要判断登录是否成功。有两种方法可以做到这一点:

A) 读取当前 URL 的查询字符串(参见 code=&lt;code&gt; 部分——这可用于检索有关您的用户的其他信息,或者可以将其发送到您的后端服务器)。

B) 使用 Facebook SDK 使用 FB.getLoginStatus(yourCallback) 检索登录状态

如果您已经在使用 SDK 和FB.login(yourCallback),您也可以将yourCallback 添加到FB.getLoginStatus。您还可以根据用户的设备同时支持弹出流和重定向流。

我建议阅读我在上面发布的文档条目以获取更多信息和选项。

【讨论】:

  • 这应该被标记为接受的答案,也就是使用 PWA 实现 Facebook 登录的方式。谢谢@nicoqh
  • Nad 你如何实现在应用程序中而不是在浏览器选项卡中打开 facebook 对话框?
【解决方案2】:

我想出了一种方法来为 FB 做这件事。使用 FB PHP SDK 生成登录 url 并在子窗口上打开该 url,整个登录对话框和权限发生,它重定向到我的 redirect_url,我使用 window.opener.postMessage 将必要的数据传递给父窗口。

我的 redirect_url 页面是这样设置的:

<?php
if ( ! session_id()) {
session_start();
}

require_once "vendor/autoload.php";

$_SESSION['FBRLH_state'] = $_GET['state'];
$fb = new Facebook\Facebook([
'app_id'                => 'FBID', // Replace {app-id} with your app id
'app_secret'            => 'FBSECRET',
'default_graph_version' => 'v2.2',
]);

$helper = $fb->getRedirectLoginHelper();

try {
$accessToken = $helper->getAccessToken();
} catch (Facebook\Exceptions\FacebookResponseException $e) {
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch (Facebook\Exceptions\FacebookSDKException $e) {
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}

if ( ! isset($accessToken)) {
if ($helper->getError()) {
    header('HTTP/1.0 401 Unauthorized');
    echo "Error: " . $helper->getError() . "\n";
    echo "Error Code: " . $helper->getErrorCode() . "\n";
    echo "Error Reason: " . $helper->getErrorReason() . "\n";
    echo "Error Description: " . $helper->getErrorDescription() . "\n";
} else {
    header('HTTP/1.0 400 Bad Request');
    echo 'Bad request';
}
exit;
}

$oAuth2Client = $fb->getOAuth2Client();

$tokenMetadata = $oAuth2Client->debugToken($accessToken);
$tokenMetadata->validateAppId('FBID'); // Replace {app-id} with your app id
$tokenMetadata->validateExpiration();

if ( ! $accessToken->isLongLived()) {
try {
    $accessToken = $oAuth2Client->getLongLivedAccessToken($accessToken);
} catch (Facebook\Exceptions\FacebookSDKException $e) {
    echo "<p>Error getting long-lived access token: " . $helper->getMessage() . "</p>\n\n";
    exit;
}}

$_SESSION['fb_access_token'] = (string)$accessToken;
$tk = $_SESSION['fb_access_token']; 
?>

<?= $tk;?>
<script type="text/javascript">
window.opener.postMessage({token: '<?= $tk;?>'}, '*');
window.close();
</script>

在父窗口中,我有一个 eventListener,它使用window.addEventListener("message", receiveMessage, false); 监听 postMessage,并且 receiveMessage 函数根据需要处理所有数据。所以任何使用独立模式的网络应用程序都应该能够从子窗口获取数据。

Window postmessage 可用于跨域之间传递数据。关于 postMessage 的更多细节在这里:https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage

【讨论】:

  • 如何在 PWA 的子窗口中打开 url?
猜你喜欢
  • 1970-01-01
  • 2018-05-11
  • 1970-01-01
  • 2017-12-06
  • 1970-01-01
  • 1970-01-01
  • 2016-11-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多