Facebook Callback appends '#_=_' to Return

2018-12-31 21:14发布

Facebook callback has started appending #_=_ hash underscore to the Return URL

Does anyone know why? What is the solution?

21条回答
情到深处是孤独
2楼-- · 2018-12-31 21:44

This was implemented by Facebook by design for security reasons. Here's the explanation from Eric Osgood, a Facebook Team member:

This has been marked as 'by design' because it prevents a potential security vulnerability.

Some browsers will append the hash fragment from a URL to the end of a new URL to which they have been redirected (if that new URL does not itself have a hash fragment).

For example if example1.com returns a redirect to example2.com, then a browser going to example1.com#abc will go to example2.com#abc, and the hash fragment content from example1.com would be accessible to a script on example2.com.

Since it is possible to have one auth flow redirect to another, it would be possible to have sensitive auth data from one app accessible to another.

This is mitigated by appending a new hash fragment to the redirect URL to prevent this browser behavior.

If the aesthetics, or client-side behavior, of the resulting URL are of concern, it would be possible to use window.location.hash (or even a server-side redirect of your own) to remove the offending characters.

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

查看更多
皆成旧梦
3楼-- · 2018-12-31 21:45

I do not see how this problem is related to facebook AJAX. In fact the issue also occurs with JavaScript disabled and purely redirect based logins.

An example exchange with 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#_  

Happens only with Firefox for me too.

查看更多
若你有天会懂
4楼-- · 2018-12-31 21:48

For PHP SDK users

I fixed the problem simply by removing the extra part before forwarding.

 $loginURL = $helper->getLoginUrl($redirectURL, $fbPermissions);
 $loginURL = str_replace("#_=_", "", $loginURL);
 header("Location: " . $loginURL);
查看更多
萌妹纸的霸气范
5楼-- · 2018-12-31 21:50

I use this one, to delete '#' symbol as well.

<script type="text/javascript">
    if (window.location.hash && window.location.hash == '#_=_') {
        window.location.href = window.location.href.split('#_=_')[0];
    }
</script>
查看更多
流年柔荑漫光年
6楼-- · 2018-12-31 21:51

via Facebook's Platform Updates:

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.

To prevent this, set the redirect_uri in your login url request like so: (using Facebook php-sdk)

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

UPDATE

The above is exactly as the documentation says to fix this. However, Facebook's documented solution does not work. Please consider leaving a comment on the Facebook Platform Updates blog post and follow this bug to get a better answer. Until then, add the following to your head tag to resolve this issue:

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

Or a more detailed alternative (thanks 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>
查看更多
深知你不懂我心
7楼-- · 2018-12-31 21:51

This can become kind of a serious issue if you're using a JS framework with hashbang (/#!/) URLs, e.g. Angular. Indeed, Angular will consider URLs with a non-hashbang fragment as invalid and throw an error :

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

If you're in such a case (and redirecting to your domain root), instead of doing :

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

Simply do :

window.location.hash = '!'; // goes to /#!, which allows Angular to take care of the rest
查看更多
登录 后发表回答