Facebookコールバックが#_=_
戻りURLにハッシュアンダースコアを追加し始めました
なぜ誰か知っていますか?解決策は何ですか?
#_=_
あなたがいても、その後、所定の位置にあるResponse.Redirect
、あなたが実際に何をしたい場所に、ブラウザは、ハッシュを維持する理由です、機能するのは、以下で提案されているクライアント側の回避策だけです。
Facebookコールバックが#_=_
戻りURLにハッシュアンダースコアを追加し始めました
なぜ誰か知っていますか?解決策は何ですか?
#_=_
あなたがいても、その後、所定の位置にあるResponse.Redirect
、あなたが実際に何をしたい場所に、ブラウザは、ハッシュを維持する理由です、機能するのは、以下で提案されているクライアント側の回避策だけです。
回答:
セッションリダイレクト動作の変更
今週は、このフィールドを空白のままにして、#____ = ____フラグメントをredirect_uriに追加し始めました。アプリがこの動作を処理できることを確認してください。
これを防ぐには、次のようにログインURLリクエストにredirect_uriを設定します(Facebook php-sdkを使用)。
$facebook->getLoginUrl(array('redirect_uri' => $_SERVER['SCRIPT_URI'],'scope' => 'user_about_me'));
更新
上記は、ドキュメントがこれを修正するように言っているとおりです。ただし、Facebookの文書化されたソリューションは機能しません。Facebook Platform Updatesブログ投稿にコメントを残すことを検討し、このバグをフォローしてより適切な回答を取得してください。それまでは、headタグに次のコードを追加して、この問題を解決してください。
<script type="text/javascript">
if (window.location.hash && window.location.hash == '#_=_') {
window.location.hash = '';
}
</script>
またはより詳細な代替手段(niftylettuceに感謝):
<script type="text/javascript">
if (window.location.hash && window.location.hash == '#_=_') {
if (window.history && history.pushState) {
window.history.pushState("", document.title, window.location.pathname);
} else {
// Prevent scrolling by storing the page's current scroll offset
var scroll = {
top: document.body.scrollTop,
left: document.body.scrollLeft
};
window.location.hash = '';
// Restore the scroll offset, should be flicker free
document.body.scrollTop = scroll.top;
document.body.scrollLeft = scroll.left;
}
}
</script>
TL; DR
if (window.location.hash === "#_=_"){
history.replaceState
? history.replaceState(null, null, window.location.href.split("#")[0])
: window.location.hash = "";
}
ステップバイステップの説明付きのフルバージョン
// Test for the ugliness.
if (window.location.hash === "#_=_"){
// Check if the browser supports history.replaceState.
if (history.replaceState) {
// Keep the exact URL up to the hash.
var cleanHref = window.location.href.split("#")[0];
// Replace the URL in the address bar without messing with the back button.
history.replaceState(null, null, cleanHref);
} else {
// Well, you're on an old browser, we can get rid of the _=_ but not the #.
window.location.hash = "";
}
}
ステップバイステップ:
fragment
isの場合のみ、コードブロックに入ります#_=_
。window.replaceState
メソッドをサポートしているかどうかを確認します。
#
て最初の部分のみを取得することにより、URLをクリーンアップします。history
きれいなURLで現在のページの状態を交換します。これにより、新しい履歴エントリが作成される代わりに、現在の履歴エントリが変更されます。これが意味することは、戻るボタンと進むボタンが思い通りに機能することです。;-)#_-_
。の詳細をご覧くださいhistory.replaceState
。
の詳細をご覧くださいwindow.location
。
URLから残りの「#」を削除する場合
$(window).on('load', function(e){
if (window.location.hash == '#_=_') {
window.location.hash = ''; // for older browsers, leaves a # behind
history.pushState('', document.title, window.location.pathname); // nice and clean
e.preventDefault(); // no page reload
}
})
e
。
これは、セキュリティ上の理由からFacebookによって設計によって実装されました。FacebookチームのメンバーであるEric Osgoodからの説明は次のとおりです。
これは、潜在的なセキュリティの脆弱性を防ぐため、「設計による」とマークされています。
一部のブラウザは、URLからのハッシュフラグメントを、リダイレクト先の新しいURLの末尾に追加します(その新しいURL自体にハッシュフラグメントがない場合)。
たとえば、example1.comがexample2.comへのリダイレクトを返す場合、example1.com#abcにアクセスするブラウザーはexample2.com#abcに移動し、example1.comのハッシュフラグメントコンテンツはexample2のスクリプトにアクセスできます。 .com。
ある認証フローを別の認証フローにリダイレクトすることが可能であるため、あるアプリから別のアプリにアクセスできる機密認証データを持つことが可能です。
これは、新しいURLフラグメントをリダイレクトURLに追加して、このブラウザーの動作を防ぐことにより軽減されます。
結果のURLの美観、つまりクライアント側の動作が問題になる場合は、window.location.hash(または独自のサーバー側リダイレクト)を使用して問題のある文字を削除することができます。
Facebookはフレームを使用し、その内部ではすべてAJAX通信を使用して機能します。この場合の最大の問題は、現在のページの状態を保持することです。私が理解している限り、Facebookはシミュレートされたアンカーを使用することにしました。つまり、どこかをクリックすると、ページ内のアンカーとしてシミュレーションされ、AJAX通信が開始されると、URLのアンカービットも変更されます。
このソリューションはF5、ブラウザがアンカー付きのURL全体をFacebookサーバーに送信するため、ページをリロードしようとするとき(ENTERではなく、を押す)に通常役立ちます。したがって、Facebookは最新の状態(表示)を取得し、そこから続行できます。
コールバックが#_=_
それとともに戻るときは、ページが離れる前の基本状態にあったことを意味します。このアンカーはブラウザによって解析されるため、心配する必要はありません。
特にURIを解析し、$ _ GETを読み取るだけではないアプリにとっては、非常に煩わしいです...これが私が一緒に投げたハックです...楽しんでください!
<html xmlns:fb='http://www.facebook.com/2008/fbml'>
<head>
<script type="text/javascript">
// Get rid of the Facebook residue hash in the URI
// Must be done in JS cuz hash only exists client-side
// IE and Chrome version of the hack
if (String(window.location.hash).substring(0,1) == "#") {
window.location.hash = "";
window.location.href=window.location.href.slice(0, -1);
}
// Firefox version of the hack
if (String(location.hash).substring(0,1) == "#") {
location.hash = "";
location.href=location.href.substring(0,location.href.length-3);
}
</script>
</head>
<body>
URI should be clean
</body>
</html>
これは、Angularなどのハッシュバング(/#!/)URLを持つJSフレームワークを使用している場合、深刻な問題になる可能性があります。実際、Angularはハッシュバン以外のフラグメントを持つURLを無効と見なし、エラーをスローします。
Error: Invalid url "http://example.com/#_=_", missing hash prefix "#!".
あなたがそのような場合(そしてあなたのドメインルートにリダイレクトする)なら、代わりに:
window.location.hash = ''; // goes to /#, which is no better
単に行う:
window.location.hash = '!'; // goes to /#!, which allows Angular to take care of the rest
この問題がFacebook AJAXにどのように関連しているかはわかりません。実際、この問題はJavaScriptが無効になっていて、純粋にリダイレクトベースのログインでも発生します。
Facebookとの交換の例:
1. GET <https://www.facebook.com/dialog/oauth?client_id=MY_APP_ID&scope=email&redirect_uri=MY_REDIRECT_URL> RESPONSE 302 Found Location: <https://www.facebook.com/connect/uiserver.php?[...]>
2. GET <https://www.facebook.com/connect/uiserver.php?[...]> RESPONSE 302 Found MY_REDIRECT_URL?code=FB_CODE#_
3. GET MY_REDIRECT_URL?code=FB_CODE#_
私にとってもFirefoxでのみ起こります。
角度と角度のuiルーターを使用すると、これを修正できます
app.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
// Make a trailing slash optional for all routes
// - Note: You'll need to specify all urls with a trailing slash if you use this method.
$urlRouterProvider.rule(function ($injector, $location) {
/***
Angular misbehaves when the URL contains a "#_=_" hash.
From Facebook:
Change in Session Redirect Behavior
This week, we started adding a fragment #_=_ to the redirect_uri when this field is left blank.
Please ensure that your app can handle this behavior.
Fix:
http://stackoverflow.com/questions/7131909/facebook-callback-appends-to-return-url#answer-7297873
***/
if ($location.hash() === '_=_'){
$location.hash(null);
}
var path = $location.url();
// check to see if the path already has a slash where it should be
if (path[path.length - 1] === '/' || path.indexOf('/?') > -1) {
return;
}
else if (path.indexOf('?') > -1) {
$location.replace().path(path.replace('?', '/?'));
}
else {
$location.replace().path(path + '/');
}
});
// etc ...
});
});
Facebookがセッションのリダイレクトを処理する方法に最近変更が加えられました。発表については、今週のOperation Developer Loveブログ投稿の「セッションリダイレクト動作の変更」を参照してください。
私は、JavaScriptを別のページにリダイレクトして、を取り除き#_=_
ます。以下のアイデアはうまくいくはずです。:)
function redirect($url){
echo "<script>window.location.href='{$url}?{$_SERVER["QUERY_STRING"]}'</script>";
}
(Backbone.jsを使用して)私にとってうまくいった回避策は、Facebookに渡されたリダイレクトURLの末尾に「#/」を追加することでした。Facebookは提供されたフラグメントを保持し、独自の「_ = _」を追加しません。
戻ると、Backboneは「#/」の部分を削除します。AngularJSの場合、「#!」を追加します 戻りURLが機能するはずです。
リダイレクトURLにもフラグメント識別子がない場合を除き、元のURLのフラグメント識別子は、ほとんどのブラウザーによるリダイレクト(HTTPステータスコード300、301、302、303を介して)で保持されることに注意してください。これは推奨される動作のようですです。
ユーザーを別の場所にリダイレクトするハンドラースクリプトを使用する場合、ここでリダイレクトURLに「#」を追加して、フラグメント識別子を空の文字列に置き換えることができます。
私はこの返信が遅いことを知っていますが、passportjsを使用している場合は、これを確認することをお勧めします。
return (req, res, next) => {
console.log(req.originalUrl);
next();
};
このミドルウェアを作成してExpressサーバーインスタンスに適用したところ、取得した元のURLにはがありません"#_=_"
。passporJSのインスタンスをミドルウェアとしてサーバーインスタンスに適用すると、これらの文字は使用されませんが、ブラウザのアドレスバーにのみ表示されます。
Angular 2(RC5)とハッシュベースのルートを使用して、これを行います:
const appRoutes: Routes = [
...
{path: '_', redirectTo: '/facebookLoginSuccess'},
...
]
そして
export const routing = RouterModule.forRoot(appRoutes, { useHash: true });
私が理解している限り=
、ルート内の文字はオプションのルートパラメータ定義の一部として解釈されます(https://angular.io/docs/ts/latest/guide/router.html#!#optional-route-parametersを参照)なので、ルートマッチングには関与しません。
"#_ = _"を削除する最も簡単でクリーンなソリューション(PHP):
「header( "Location:xxx.php");」の代わりに 「echo( "location.href = 'xxx.php';");」を使用するには