PWA webisteを構築しています。私はAngular JSを使用しており、私のWebサイトで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のログイン画面を開いており、認証情報を入力した後、何も表示されません。アプリに戻らない。 manifest.jsonファイルで、displayプロパティはスタンドアロンに設定されています。助けてください。
ユーザーがログインするためのFacebook APIがログインフォームで新しいタブを開くため、これは正しい動作です。 FacebookはOAuth2ソリューションを実装し、APIを使用してユーザーを認証するためにOAuth2 Implicit Flowをアクティブ化します。同じウィンドウでログインするには認証コードを使用する必要がありますが、クライアント側のアプリケーションではユーザーが利用できない秘密コードが必要になるため安全ではありません。
新しいタブを開く代わりに、Facebookのログインフォームを使用してiframeを作成し、ユーザーがログインしたときに閉じてリダイレクトすることができます。
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ログインページを開く関数を記述します。
このTypeScriptの例は、アクセストークンのpromiseを返し、ユーザーがメールアクセスを許可しているかどうかを確認します。
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;
}