如果应用程序处于独立状态,则Facebook登录无法在PWA应用程序中运行

时间:2018-01-05 11:05:43

标签: angularjs facebook-login progressive-web-apps

我正在建立一个PWA网站。我正在使用Angular JS,我在我的网站上使用javascript facebook登录。但如果我在浏览器中查看我的应用程序,Facebook登录正在运行。但是当我向主屏幕添加快捷方式并从主屏幕启动应用程序时,FB登录无效。正在加载Facebook页面。但输入凭据后,它显示空白页面。有人可以帮忙吗?

这是我的FB登录代码

var doBrowserLogin = function(){
  var deferred = $q.defer();
  FB.login(
    function(response){
      if (response.authResponse) {
              deferred.resolve(response);
            }else{
              deferred.reject(response);
            }
          },
          {scope:'email,public_profile'}
       );
  return deferred.promise;
}

它正在打开Facebook登录屏幕,输入凭据后,它显示为空白。没有回到应用程序。 Blank page 在我的manifest.json文件中,display属性设置为standalone。 请帮忙。

2 个答案:

答案 0 :(得分:2)

这是正确的行为,因为Facebook API登录用户使用登录表单打开新选项卡。 Facebook实施OAuth2解决方案,并使用他们的API验证用户激活OAuth2隐式流。要在同一窗口中登录,您必须使用授权码,但对于客户端应用程序是不安全的,因为您需要一个不可供用户使用的密码。

您可以使用Facebook登录表单创建iframe,并在用户登录时关闭并重定向,而不是打开新标签。

答案 1 :(得分:2)

不要使用Facebook javascript插件,请编写您自己的流程:

1)创建一个将接收fb登录响应的静态html(例如:/fb-login-receiver.html) 它将使用postMessage将登录结果发送回应用程序。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    Facebook login completed.
    <script type="text/javascript">
    window.opener.postMessage(window.location.toString(), window.location.href);
    window.close();
  </script>
</body>
</html>

2)在您的应用程序中编写一个函数,该函数将在弹出窗口中打开fb登录页面

此打字稿示例返回对访问令牌的承诺,并检查用户是否允许电子邮件访问:

async loginFacebook(): Promise<string> {
    let popup = window.open("https://www.facebook.com/v3.1/dialog/oauth?client_id=**<YOUR_CLIENT_ID>**&display=popup&scope=email&response_type=token,granted_scopes&auth_type=rerequest&redirect_uri=" + window.location.origin + "/fb-login-receiver.html", 'Facebook Login', 'width=500,height=500');
    var promise = new Promise<string>((resolve, reject) => {
      let finished = false;
      let listener = (e: MessageEvent) => {
        finished = true;
        let url = new URL(e.data);
        let hash = url.hash.substring(1);
        let splitted = hash.split('&');
        let dct: { [key: string]: string } = {};
        for (let s of splitted) {
          var spltd = s.split('=');
          dct[spltd[0]] = spltd[1];
        }

        if (dct['granted_scopes'].indexOf('email') < 0) {
          reject("Email required");
          return;
        }
        resolve(dct['access_token']);
      };
      addEventListener('message', listener);

      let intervalChecker = setInterval(() => {
        if (popup.closed) {
          clearInterval(intervalChecker);
          removeEventListener('message', listener);
          if (!finished) {
            reject('Login canceled');
          }
        }
      }, 10);
    });
    return promise;
}