it-swarm.com.de

Facebook Callback fügt '# _ = _' an die Rückgabe-URL an

Facebook Callback hat begonnen, #_=_ Hash-Unterstrich an die Return URL anzuhängen

Weiß jemand warum? Was ist die Lösung?

442
zing ming

via Facebook-Plattformaktualisierungen :

Ändern Sie das Verhalten der Sitzungsumleitung

Diese Woche haben wir begonnen, ein Fragment # ____ = ____ zum Redirect_uri hinzuzufügen, wenn Dieses Feld ist leer. Bitte stellen Sie sicher, dass Ihre App damit umgehen kann Verhalten.

Um dies zu verhindern, setzen Sie die Weiterleitungsadresse in Ihrer Login-URL-Anfrage folgendermaßen: (mit Facebook php-sdk)

$facebook->getLoginUrl(array('redirect_uri' => $_SERVER['SCRIPT_URI'],'scope' => 'user_about_me'));

UPDATE

Das obige ist genau wie in der Dokumentation , um dies zu beheben. Die dokumentierte Lösung von Facebook funktioniert jedoch nicht. Bitte hinterlasse einen Kommentar zum Blogeintrag Facebook Platform Updates und folge diesem Fehler , um eine bessere Antwort zu erhalten. Fügen Sie Ihrem head-Tag bis dahin Folgendes hinzu, um dieses Problem zu beheben:

<script type="text/javascript">
    if (window.location.hash && window.location.hash == '#_=_') {
        window.location.hash = '';
    }
</script>

Oder eine detailliertere Alternative (danke 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>
229
Ryan

TL; DR

if (window.location.hash === "#_=_"){
    history.replaceState 
        ? history.replaceState(null, null, window.location.href.split("#")[0])
        : window.location.hash = "";
}

Vollversion mit Schritt für Schritt Anleitung

// 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 = "";

    }

}

Schritt für Schritt:

  1. Wir gelangen nur in den Codeblock, wenn fragment#_=_ ist.
  2. Prüfen Sie, ob der Browser die HTML5-Methode window.replaceState unterstützt .
    1. Reinigen Sie die URL, indem Sie # teilen und nur den ersten Teil übernehmen.
    2. Teilen Sie history mit, den aktuellen Seitenstatus durch die saubere URL zu ersetzen. Dadurch wird der aktuelle Verlaufseintrag geändert, anstatt einen neuen zu erstellen. Dies bedeutet, dass die Vor- und Zurück-Tasten genau so funktionieren, wie Sie es wünschen. ;-)
  3. Wenn der Browser die fantastischen HTML 5-Historienmethoden nicht unterstützt, bereinigen Sie die URL so gut wie möglich, indem Sie den Hash auf leere Zeichenfolge setzen. Dies ist ein schlechter Fallback, da immer noch ein nachfolgender Hash (example.com/#) hinterlassen wird und es außerdem einen Verlaufseintrag hinzufügt. Mit der Zurück-Taste gelangen Sie zurück zu #_-_

Erfahren Sie mehr über history.replaceState .

Erfahren Sie mehr über window.location .

99
PapaSierra

wenn Sie das verbleibende "#" von der URL entfernen möchten

$(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
  }
})
57
likebeats

Dies wurde von Facebook aus Sicherheitsgründen konstruktiv umgesetzt. Hier ist die Erklärung von Eric Osgood, einem Mitglied des Facebook-Teams:

Dies wurde als "Design" markiert weil es eine potenzielle Sicherheitslücke verhindert.

Einige Browser hängen das Hash-Fragment von einer URL an das Ende einer .__ an. Neue URL, zu der sie umgeleitet wurden (wenn diese neue URL nicht selbst ein Hash-Fragment hat).

Wenn beispielsweise example1.com eine Weiterleitung an example2.com zurückgibt, dann eine Browser, der zu example1.com # abc wechselt, wird zu example2.com # abc und der Hash-Fragment-Inhalte von example1.com sind für eine .__ zugänglich. Skript auf example2.com.

Da es möglich ist, einen Auth-Fluss auf einen anderen umzuleiten, ist es Es wäre möglich, sensible Authentifizierungsdaten von einer App aus zugänglich zu haben zum anderen.

Dies wird dadurch gemildert, dass ein neues Hash-Fragment an die Weiterleitungs-URL angehängt wird um dieses Browserverhalten zu verhindern.

Wenn die Ästhetik oder das clientseitige Verhalten der resultierenden URL .__ ist. Besorgnis erregend wäre es möglich, window.location.hash (oder sogar eine eigene serverseitige Umleitung) zu verwenden, um das fehlerhafte .__ zu entfernen. Zeichen.

Quelle: https://developers.facebook.com/bugs/318390728250352/

33
Mark Murphy

Sie sind sich nicht sicher, warum sie das tun, aber Sie können dies umgehen, indem Sie den Hash oben auf Ihrer Seite zurücksetzen:

if (window.location.hash == "#_=_")
  window.location.hash = "";
10
mixmasteralan

Sie können auch einen eigenen Hash im redirect_uri-Parameter für den Facebook-Rückruf angeben. Dies kann in bestimmten Situationen hilfreich sein, z. /api/account/callback#home. Wenn Sie zurückgeleitet werden, ist es mindestens ein Hash, der einer bekannten Route entspricht, wenn Sie backbone.js oder ähnliches verwenden (nicht sicher über jquery mobile).

9
pkiddie

Ärgerlich, vor allem für Apps, die die URI analysieren und nicht nur $ _GET lesen ... Hier ist der Hack, den ich zusammen warf ... Viel Spaß!

<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>
8
Jeremy Whitt

Facebook verwendet einen Frame und in diesem funktioniert alles über AJAX Kommunikation. Das größte Problem ist in diesem Fall, den aktuellen Seitenstatus beizubehalten. Soweit ich weiß, entschied sich Facebook für simulierte Anker. Wenn Sie also auf eine beliebige Stelle geklickt haben, wird diese als Anker innerhalb Ihrer Seite simuliert. Wenn die AJAX -Kommunikation gestartet wird, wird auch das Ankerbit Ihrer URL geändert.

Diese Lösung hilft Ihnen normalerweise, wenn Sie versuchen, die Seite neu zu laden (nicht ENTER, drücken Sie F5), weil Ihr Browser die gesamte URL mit Ankern an den Facebook-Server sendet. Daher nimmt Facebook den neuesten Stand (was Sie sehen) und Sie können von dort aus fortfahren.

Wenn der Rückruf mit #_=_ zurückgegeben wird, bedeutet dies, dass sich die Seite vor dem Verlassen im Grundzustand befunden hat. Da dieser Anker vom Browser analysiert wird, müssen Sie sich darüber keine Gedanken machen.

8
Sándor Tóth

Dies kann zu einem ernsthaften Problem werden, wenn Sie ein JS-Framework mit Hash-URLs (/ #! /) Verwenden, z. Winkelig Angular betrachtet URLs mit einem Nicht-Hashbang-Fragment als ungültig und gibt einen Fehler aus:

Error: Invalid url "http://example.com/#_=_", missing hash prefix "#!".

Wenn Sie sich in einem solchen Fall befinden (und auf Ihr Domänenstammverzeichnis umleiten), müssen Sie Folgendes tun:

window.location.hash = ''; // goes to /#, which is no better

Einfach machen:

window.location.hash = '!'; // goes to /#!, which allows Angular to take care of the rest
6
neemzy

Ich sehe nicht, wie dieses Problem mit Facebook AJAX zusammenhängt. In der Tat tritt das Problem auch bei deaktiviertem JavaScript und rein umgeleiteten Anmeldungen auf. 

Ein Beispiel zum Austausch mit 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#_  

Das passiert auch nur mit Firefox für mich.

5
Sebastian Tusk

Das Hinzufügen zu meiner Weiterleitungsseite hat das Problem für mich behoben ...

if (window.location.href.indexOf('#_=_') > 0) {
    window.location = window.location.href.replace(/#.*/, '');
}
4
neokio

Sie können dies mit dem ei-Router mit eckigem und eckigem Winkel beheben 

    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 ...
    });
});
3
rebelliard

Wenn Sie einen vue-router verwenden, können Sie der Liste der Routen hinzufügen:

{
  path: '/_=_',
  redirect: '/', // <-- or other default route
},
2
Slawomir

Kürzlich wurde eine Änderung im Umgang mit Sitzungsweiterleitungen bei Facebook eingeführt. Weitere Informationen finden Sie unter "Ändern des Verhaltens für Sitzungsumleitungen" im diesjährigen Operation Developer Love Blogpost.

2
Dhiren Patel

Für mich mache ich JavaScript-Weiterleitung auf eine andere Seite, um #_=_ loszuwerden. Die folgenden Ideen sollten funktionieren. :)

function redirect($url){
    echo "<script>window.location.href='{$url}?{$_SERVER["QUERY_STRING"]}'</script>";        
}
2
Eng Cy

Ich verwende dieses, um auch das '#' Symbol zu löschen.

<script type="text/javascript">
    if (window.location.hash && window.location.hash == '#_=_') {
        window.location.href = window.location.href.split('#_=_')[0];
    }
</script>
1
Simon

Ich weiß, dass diese Antwort zu spät kommt, aber wenn Sie Passjobs verwenden, möchten Sie dies vielleicht sehen. 

return (req, res, next) => {
    console.log(req.originalUrl);
    next();
};

Ich habe diese Middleware geschrieben und auf die Express-Serverinstanz angewendet, und die ursprüngliche URL, die ich habe, ist ohne den "#_=_". Sieht so aus, wenn wir die Instanz von passporJS als Middleware auf die Serverinstanz anwenden. Diese Zeichen sind nicht erforderlich, sondern nur in der Adressleiste unserer Browser sichtbar. 

1
Krishna

Eine Problemumgehung, die für mich funktionierte (mithilfe von Backbone.js), war das Hinzufügen von "# /" am Ende der an Facebook übergebenen Weiterleitungs-URL. Facebook behält das bereitgestellte Fragment bei und fügt nicht sein eigenes "_ = _" hinzu.

Nach der Rückkehr entfernt Backbone den Teil "# /". Für AngularJS das Anhängen von "#!" auf die zurückgegebene URL sollte funktionieren.

Beachten Sie, dass die Fragmentkennung der ursprünglichen URL bei der Umleitung (über die HTTP-Statuscodes 300, 301, 302 und 303) von den meisten Browsern beibehalten wird, es sei denn, die Umleitungs-URL verfügt auch über eine Fragmentkennung. Dieses scheint ein empfohlenes Verhalten zu sein.

Wenn Sie ein Handler-Skript verwenden, das den Benutzer an eine andere Stelle umleitet, können Sie hier "#" an die Weiterleitungs-URL anhängen, um die Fragment-ID durch eine leere Zeichenfolge zu ersetzen.

1
Ivo Smits

Für PHP SDK-Benutzer

Ich habe das Problem behoben, indem ich vor dem Weiterleiten den zusätzlichen Teil entfernt habe.

 $loginURL = $helper->getLoginUrl($redirectURL, $fbPermissions);
 $loginURL = str_replace("#_=_", "", $loginURL);
 header("Location: " . $loginURL);
0
Nanoripper

Mit Angular 2 (RC5) und Hash-basierten Routen mache ich Folgendes:

const appRoutes: Routes = [
  ...
  {path: '_', redirectTo: '/facebookLoginSuccess'},
  ...
]

und

export const routing = RouterModule.forRoot(appRoutes, { useHash: true });

Soweit ich weiß, wird das =-Zeichen in der Route als Teil der Definition optionaler Routenparameter interpretiert (siehe https://angular.io/docs/ts/latest/guide/router.html#!#optional-route) -parameters ), also nicht am Routenabgleich beteiligt.

0
rcomblen

Dies würde die angehängten Zeichen an Ihrer URL entfernen

<script type="text/javascript">
 var idx=window.location.toString().indexOf("#_=_"); 
   if (idx > 0) { 
     window.location = window.location.toString().substring(0, idx); 
   } 
</script>
0