Facebook Login not working in PWA app if app is in

2019-03-17 23:46发布

问题:

I am building a PWA webiste. I am using Angular JS and I used javascript facebook login in my website. But if I view my app in browser, facebook login is working. But when I add shortcut to homescreen and launch the app from the homescreen, FB login is not working. Facebook page is loading. But after entering credentials it shows blank page. Can anyone help ?

Here is my FB login code

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;
}

It is opening the facebook login screen and after entering the credentials, it is showing blank. Not coming back to app. In my manifest.json file, the display property is set to standalone. Please help.

回答1:

This is correct behaviour because Facebook API to login user open new tab with login form. Facebook implement OAuth2 solution and for authenticate user using their API activate OAuth2 Implicit Flow. For login in the same window you must use Authorization Code, but for client side applications isn't secure beacause you will need a secret code not available for users.

Instead of open new tab you can create iframe with facebook login form and when user logged in close it and redirect.



回答2:

Don't use facebook javascript plugin, write your own flow:

1) Create a static html that will receive fb login response (ex: /fb-login-receiver.html) It will send back login result to the application with 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) In your application write a function that will open fb login page in a popup window

this typescript example returns a promise for the access token and check if the user has allowed email access:

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;
}