Abh*_*rya 7 facebook google-chrome facebook-javascript-sdk progressive-web-apps angular
我有一个使用Angular 4构建的Progressive Web App.
我的问题是当从主屏幕应用程序使用时,Fb登录对话框不会自动关闭.在Chrome浏览器中打开它时工作得很好但是当我从已安装的主屏幕应用程序使用它时,对话框窗口会打开请求权限,在给出所有权限后,对话框变为空白并且不会关闭或重定向回应用程序.
看起来如果我将manifest.json中的"display"更改为"browser",它可以工作但是当"display"处于"standalone"状态时不起作用.
我搜索了一遍但没有成功.
谢谢
当您的应用程序作为渐进式 Web 应用程序安装时,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}
Run Code Online (Sandbox Code Playgroud)
如果用户成功授予您的应用程序必要的权限,他/她将被重定向回您的应用程序(位置由 确定{redirect-url}):
{redirect-uri}?code=<facebook-code>&state={state}#_=_
Run Code Online (Sandbox Code Playgroud)
然后您的应用程序需要确定登录是否成功。有两种方法可以做到这一点:
A) 读取当前 URL 的查询字符串(请参阅 部分code=<code>- 这可用于检索有关您的用户的其他信息,或者可以将其发送到您的后端服务器)。
B) 使用 Facebook SDK 检索登录状态FB.getLoginStatus(yourCallback)
如果您已经在使用 SDK 和,您也FB.login(yourCallback)可以添加yourCallback。FB.getLoginStatus您还可以根据用户的设备支持弹出流和重定向流。
我建议阅读我上面发布的文档条目以获取更多信息和选项。
我想出了一个方法来为 FB 做到这一点。使用 FB PHP SDK 生成登录网址并在子窗口上打开该网址,整个登录对话框和权限都会发生,它会重定向到我的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>
Run Code Online (Sandbox Code Playgroud)
在父窗口中,我有一个 eventListener,它正在监听 postMessage window.addEventListener("message", receiveMessage, false);,并且 receiveMessage 函数根据需要处理所有数据。因此任何使用独立模式的 Web 应用程序都应该能够从子窗口获取数据。
Window postmessage 可用于跨域之间传递数据。有关 postMessage 的更多详细信息,请参见:https ://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
| 归档时间: |
|
| 查看次数: |
827 次 |
| 最近记录: |