Le rappel Facebook ajoute ‘# _ = _’ à ​​l’URL de retour

Le rappel de Facebook a commencé à append #_=_ soulignement de hachage à l’URL de retour

Quelqu’un sait-il pourquoi? Quelle est la solution?

via les mises à jour de la plate-forme Facebook :

Modification du comportement de redirection de session

Cette semaine, nous avons commencé à append un fragment # ____ = ____ au redirect_uri lorsque ce champ est laissé vide. Veuillez vous assurer que votre application peut gérer ce comportement.

Pour éviter cela, définissez le redirect_uri dans votre requête de connexion comme ceci: (en utilisant Facebook php-sdk)

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

METTRE À JOUR

Ce qui précède est exactement ce que la documentation dit pour résoudre ce problème. Cependant, la solution documentée de Facebook ne fonctionne pas. S’il vous plaît envisager de laisser un commentaire sur le blog de Facebook Platform Mises à jour et suivez ce bogue pour obtenir une meilleure réponse. Jusque-là, ajoutez les éléments suivants à votre balise headhead pour résoudre ce problème:

  

Ou une alternative plus détaillée (merci niftylettuce ):

  

TL; DR

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

Version complète avec instructions pas à pas

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

Pas à pas:

  1. Nous entrerons seulement dans le bloc de code si le fragment est #_=_ .
  2. Vérifiez si le navigateur prend en charge la méthode HTML5 window.replaceState.
    1. Nettoyez l’URL en divisant sur # et en ne prenant que la première partie.
    2. Indiquez à l’ history de remplacer l’état actuel de la page par l’URL propre. Cela modifie l’entrée de l’historique en cours au lieu d’en créer une nouvelle. Cela signifie que les boutons Précédent et Suivant fonctionneront comme vous le souhaitez. 😉
  3. Si le navigateur ne prend pas en charge les méthodes impressionnantes de l’historique HTML 5, nettoyez simplement l’URL du mieux possible en définissant le hachage sur une chaîne vide. C’est un mauvais retour car il laisse toujours un hachage final (example.com/#) et ajoute une entrée d’historique, donc le bouton Retour vous ramènera à #_-_ .

En savoir plus sur history.replaceState .

En savoir plus sur window.location .

si vous voulez supprimer le “#” restant de l’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 } }) 

Cela a été mis en œuvre par Facebook pour des raisons de sécurité. Voici l’explication d’Eric Osgood, membre de l’équipe Facebook:

Cela a été marqué comme «par conception», car il empêche une vulnérabilité potentielle de sécurité.

Certains navigateurs ajoutent le fragment de hachage d’une URL à la fin d’une nouvelle URL à laquelle ils ont été redirigés (si cette nouvelle URL ne contient pas de fragment de hachage).

Par exemple, si example1.com renvoie une redirection vers example2.com, un navigateur allant dans example1.com # abc ira dans example2.com # abc et le contenu du fragment de hachage de example1.com sera accessible à un script sur example2. .com.

Comme il est possible de redirect un stream d’authentification vers une autre, il serait possible d’avoir des données d’authentification sensibles d’une application accessible à une autre.

Cela est atténué en ajoutant un nouveau fragment de hachage à l’URL de redirection pour empêcher ce comportement du navigateur.

Si l’esthétique, ou le comportement côté client, de l’URL résultante est préoccupant, il serait possible d’utiliser window.location.hash (ou même une redirection côté serveur) pour supprimer les caractères incriminés.

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

Vous ne savez pas pourquoi ils font cela, mais vous pouvez contourner ce problème en réinitialisant le hachage en haut de votre page:

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

Facebook utilise un cadre et à l’intérieur de celui-ci tout fonctionne en utilisant la communication AJAX. Le plus gros problème dans ce cas est de préserver l’état de la page en cours. Pour autant que je comprenne, Facebook a décidé d’utiliser des ancres simulées. Cela signifie que si vous avez cliqué quelque part, ils simulent cela comme une ancre à l’intérieur de votre page, et lorsque la communication AJAX démarre, ils modifient également le bit d’ancrage de votre URL.

Cette solution vous aide normalement lorsque vous essayez de recharger la page (pas ENTER, appuyez sur F5 ), car votre navigateur envoie l’URL complète avec des ancres au serveur Facebook. Par conséquent, Facebook récupère le dernier état (ce que vous voyez) et vous pouvez ensuite continuer à partir de là.

Lorsque le rappel revient avec #_=_ cela signifie que la page était dans son état de base avant de la quitter. Parce que cette ancre est analysée par le navigateur, vous n’avez pas à vous en soucier.

Vous pouvez également spécifier votre propre hachage sur le paramètre redirect_uri pour le rappel Facebook, ce qui peut être utile dans certaines circonstances, par exemple /api/account/callback#home . Lorsque vous êtes redirigé, ce sera au moins un hachage qui correspond à un itinéraire connu si vous utilisez backbone.js ou similaire (pas sûr de jquery mobile).

Major ennuyeux, surtout pour les applications qui parsingnt l’URI et pas seulement lire le $ _GET … Voici le hack que j’ai jeté ensemble … Enjoy!

      URI should be clean   

Cela peut devenir un problème grave si vous utilisez un framework JS avec des URL hashbang (/ #! /), Par exemple Angular. En effet, Angular considérera les URL avec un fragment non-hasbbang comme non valides et générera une erreur:

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

Si vous êtes dans un tel cas (et redirigé vers votre racine de domaine), au lieu de faire:

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

Simplement faire:

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

Je ne vois pas comment ce problème est lié à facebook AJAX. En fait, le problème se produit également avec JavaScript désactivé et purement redirect les connexions basées.

Un exemple d’échange avec 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#_ 

Cela ne se produit qu’avec Firefox pour moi aussi.

L’ajout de ceci à ma page de redirection a résolu le problème pour moi …

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

Avec un routeur ui angular et angular, vous pouvez résoudre ce problème

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

Un changement a été introduit récemment dans la manière dont Facebook gère les redirections de session. Voir “Changement de comportement de redirection de session” dans le billet de cette semaine sur le blog Operation Developer Love pour l’annonce.

Pour moi, je fais la redirection JavaScript vers une autre page pour me débarrasser de #_=_ . Les idées ci-dessous devraient fonctionner. 🙂

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

Une solution de contournement qui a fonctionné pour moi (en utilisant Backbone.js) consistait à append “# /” à la fin de l’URL de redirection transmise à Facebook. Facebook conservera le fragment fourni et ne appenda pas son propre “_ = _”.

À son retour, Backbone supprimera la partie “# /”. Pour AngularJS, append “#!” à l’URL de retour devrait fonctionner.

Notez que l’identificateur de fragment de l’URL d’origine est conservé lors de la redirection (via les codes d’état HTTP 300, 301, 302 et 303) par la plupart des navigateurs, à moins que l’URL de redirection ne comporte également un identificateur de fragment. Cela semble être un comportement recommandé .

Si vous utilisez un script de gestionnaire qui redirige l’utilisateur ailleurs, vous pouvez append “#” à l’URL de redirection ici pour remplacer l’identificateur de fragment par une chaîne vide.

Je sais que cette réponse est en retard, mais si vous utilisez passportjs, vous voudrez peut-être voir cela.

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

J’ai écrit ce middleware et je l’ai appliqué à une instance de serveur express, et l’URL d’origine que j’ai est sans "#_=_" . On dirait que lorsque nous appliquons l’instance de passporJS en tant que middleware à l’instance du serveur, cela ne prend pas ces caractères, mais n’est visible que dans la barre d’adresse de nos navigateurs.

J’utilise celui-ci, pour supprimer également le symbole “#”.

  

En utilisant Angular 2 (RC5) et les routes basées sur le hachage, je fais ceci:

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

et

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

Si je comprends bien, le caractère = dans la route est interprété comme faisant partie de la définition des parameters de route facultatifs (voir https://angular.io/docs/ts/latest/guide/router.html#!#optional-route-parameters ), donc pas impliqué dans la correspondance de route.

Pour les utilisateurs de PHP SDK

J’ai résolu le problème simplement en retirant la pièce supplémentaire avant de la transférer.

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