La richiamata di Facebook aggiunge “# _ = _” per restituire l’URL

Il callback di Facebook ha iniziato ad aggiungere #_=_ hash underscore all’URL di ritorno

Qualcuno sa perché? Qual’è la soluzione?

tramite gli aggiornamenti della piattaforma di Facebook :

Modifica nel comportamento di reindirizzamento della sessione

Questa settimana, abbiamo iniziato ad aggiungere un frammento # ____ = ____ al redirect_uri quando questo campo è stato lasciato vuoto. Assicurati che la tua app possa gestire questo comportamento.

Per evitare ciò, imposta redirect_uri nella tua richiesta di url di login in questo modo: (usando Facebook php-sdk)

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

AGGIORNARE

Quanto sopra è esattamente come dice la documentazione per risolvere questo problema. Tuttavia, la soluzione documentata di Facebook non funziona. Si prega di considerare di lasciare un commento sul post del blog Aggiornamenti piattaforma Facebook e seguire questo bug per ottenere una risposta migliore. Fino ad allora, aggiungi il seguente tag head per risolvere questo problema:

  

O un’alternativa più dettagliata (grazie niftylettuce ):

  

TL; DR

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

Versione completa con istruzioni dettagliate

 // 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 = ''; } } 

Passo dopo passo:

  1. Entreremo nel blocco di codice solo se il fragment è #_=_ .
  2. Verifica se il browser supporta il metodo window.replaceState HTML5.
    1. Pulisci l’URL dividendo su # e prendendo solo la prima parte.
    2. Racconta la history per sostituire lo stato corrente della pagina con l’URL pulito. Questo modifica la voce della cronologia corrente invece di crearne una nuova. Ciò significa che i pulsanti avanti e indietro funzioneranno esattamente come vuoi tu. 😉
  3. Se il browser non supporta i fantastici metodi di cronologia HTML 5, ripulisci l’URL al meglio impostando l’hash sulla stringa vuota. Questo è un fallback negativo perché lascia ancora un hash finale (example.com/#) e aggiunge anche una voce di cronologia, quindi il pulsante Indietro ti riporterà a #_-_ .

Ulteriori informazioni su history.replaceState .

Ulteriori informazioni su window.location .

se si desidera rimuovere il “#” rimanente dall’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 } }) 

Questo è stato implementato da Facebook per motivi di sicurezza. Ecco la spiegazione di Eric Osgood, un membro del team di Facebook:

Questo è stato contrassegnato come “design” perché impedisce una potenziale vulnerabilità di sicurezza.

Alcuni browser aggiungeranno il frammento di hash da un URL alla fine di un nuovo URL a cui sono stati reindirizzati (se il nuovo URL non ha un frammento hash).

Ad esempio se example1.com restituisce un reindirizzamento a example2.com, quindi un browser che va a example1.com # abc andrà su example2.com # abc, e il contenuto del frammento hash da example1.com sarebbe accessibile a uno script su example2 .com.

Poiché è ansible avere un reindirizzamento del stream di autenticazione a un altro, sarebbe ansible avere dati di autenticazione sensibili da un’app accessibile a un altro.

Questo viene mitigato aggiungendo un nuovo frammento di hash all’URL di reindirizzamento per impedire questo comportamento del browser.

Se l’estetica, o il comportamento lato client, dell’URL risultante sono preoccupanti, sarebbe ansible utilizzare window.location.hash (o anche un reindirizzamento lato server proprio) per rimuovere i caratteri offensivi.

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

Non sei sicuro del motivo per cui lo stanno facendo, ma potresti aggirare il problema resettando l’hash nella parte superiore della pagina:

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

Facebook usa una cornice e al suo interno tutto funziona utilizzando la comunicazione AJAX. Il problema più grande in questo caso è la conservazione dello stato corrente della pagina. Per quanto ho capito, Facebook ha deciso di utilizzare ancore simulate. Ciò significa che se fai clic da qualche parte, lo simulano come un’ancora all’interno della tua pagina e quando inizia la comunicazione AJAX, cambiano anche il bit di ancoraggio dell’URL.

Questa soluzione ti aiuta normalmente quando tenti di ricaricare la pagina (non INVIO, premi F5 ), perché il tuo browser invia l’intero URL con ancore al server di Facebook. Quindi Facebook raccoglie lo stato più recente (quello che vedi) e sei quindi in grado di continuare da lì.

Quando il callback ritorna con #_=_ significa che la pagina era nel suo stato di base prima di lasciarla. Poiché questa ancora viene analizzata dal browser, non devi preoccuparti di ciò.

È inoltre ansible specificare il proprio hash sul parametro redirect_uri per la richiamata di Facebook, che potrebbe essere utile in determinate circostanze, ad es. /api/account/callback#home . Quando si viene reindirizzati, sarà almeno un hash che corrisponde a un percorso noto se si utilizza backbone.js o simili (non si è sicuri di jquery mobile).

Major fastidioso, soprattutto per le app che analizzano l’URI e non solo per leggere $ _GET … Ecco l’hack che ho buttato insieme … Enjoy!

      URI should be clean   

Questo può diventare un problema serio se stai usando un framework JS con URL hashbang (/ #! /), Ad es. Angolare. Infatti, Angular considererà gli URL con un frammento non hashbang non valido e genererà un errore:

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

Se ti trovi in ​​questo caso (e stai reindirizzando verso la tua radice di dominio), invece di fare:

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

Basta fare:

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

Non vedo come questo problema è legato a Facebook AJAX. In realtà il problema si verifica anche con gli accessi JavaScript disabilitati e basati su reindirizzamenti puramente.

Un esempio di scambio con facebook:

 1. GET  RESPONSE 302 Found Location:  2. GET  RESPONSE 302 Found MY_REDIRECT_URL?code=FB_CODE#_ 3. GET MY_REDIRECT_URL?code=FB_CODE#_ 

Succede solo con Firefox anche per me.

Aggiungendo questo alla mia pagina di reindirizzamento risolto il problema per me …

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

Con il router ui angular e angular, è ansible risolvere questo problema

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

Recentemente è stata introdotta una modifica nel modo in cui Facebook gestisce i reindirizzamenti di sessione. Vedere “Modifica nel comportamento di reindirizzamento della sessione” nel post del blog di Operation Developer Love di questa settimana per l’annuncio.

Per me, faccio reindirizzamento JavaScript a un’altra pagina per sbarazzarsi di #_=_ . Le idee qui sotto dovrebbero funzionare. 🙂

 function redirect($url){ echo ""; } 

Una soluzione che ha funzionato per me (utilizzando Backbone.js), era quella di aggiungere “# /” alla fine dell’URL di reindirizzamento passato a Facebook. Facebook manterrà il frammento fornito e non aggiungerà il proprio “_ = _”.

Al ritorno, Backbone rimuoverà la parte “# /”. Per AngularJS, aggiungendo “#!” all’URL di ritorno dovrebbe funzionare.

Si noti che l’identificatore di frammento dell’URL originale viene conservato al reindirizzamento (tramite i codici di stato HTTP 300, 301, 302 e 303) dalla maggior parte dei browser, a meno che l’URL di reindirizzamento abbia anche un identificatore di frammento. Questo sembra essere un comportamento raccomandato .

Se si utilizza uno script di gestione che reindirizza l’utente altrove, è ansible aggiungere “#” all’URL di reindirizzamento qui per sostituire l’identificatore di frammento con una stringa vuota.

So che questa risposta è in ritardo, ma se stai usando passportjs, potresti voler vedere questo.

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

Ho scritto questo middleware e l’ho applicato per esprimere l’istanza del server, e l’URL originale che ho è senza "#_=_" . Sembra che quando applichiamo l’istanza di passporJS come middleware all’istanza del server, non prende quei caratteri, ma sono visibili solo nella barra degli indirizzi dei nostri browser.

Io uso questo, per eliminare anche il simbolo ‘#’.

  

Utilizzando Angular 2 (RC5) e route basate su hash, io faccio questo:

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

e

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

Per quanto ho capito, il carattere = nella route è interpretato come parte della definizione dei parametri del percorso facoltativo (consultare https://angular.io/docs/ts/latest/guide/router.html#!#optional-route-parameters ), quindi non coinvolto nella corrispondenza del percorso.

Per gli utenti di SDK PHP

Ho risolto il problema semplicemente rimuovendo la parte extra prima di inoltrare.

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