it-swarm-ko.com

Facebook 콜백은 '# _ = _'을 (를) 반환 URL에 추가합니다.

Facebook 콜백이 #_=_ 해시 밑줄을 반환 URL에 추가하기 시작했습니다.

그 이유를 아는 사람 있습니까? 해결책은 무엇인가?

453
zing ming

via 페이스 북의 플랫폼 업데이트 :

세션 리디렉션 동작 변경

이번 주, 우리는이 필드가 비어있을 때 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>
231
Ryan

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

    }

}

단계별 :

  1. fragment#_=_ 인 경우에만 코드 블록으로 들어갑니다.
  2. 브라우저가 HTML5 window.replaceState 메소드를 지원하는지 확인하십시오.
    1. #로 분할하고 첫 번째 부분 만 가져 와서 URL을 정리하십시오.
    2. 현재 페이지 상태를 깨끗한 URL로 바꾸려면 history에 지시하십시오. 이렇게하면 현재 기록 항목이 새로 작성되는 대신 수정됩니다. 이것이 의미하는 바는 뒤로 및 앞으로 단추가 원하는대로 작동한다는 것입니다. ;-)
  3. 브라우저가 멋진 HTML 5 히스토리 메소드를 지원하지 않는다면 해시를 빈 문자열로 설정하여 가능한 한 URL을 정리하십시오. 이는 후행 해시 (example.com/#)를 남기고 기록 항목을 추가하기 때문에 가난한 대체 수단이기 때문에 뒤로 버튼을 누르면 #_-_로 돌아갑니다.

history.replaceState 에 대해 자세히 알아보십시오.

window.location 에 대해 자세히 알아보십시오.

105
PapaSierra

나머지 "#"을 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
  }
})
58
likebeats

이는 보안상의 이유로 Facebook에서 구현 한 것입니다. 다음은 Facebook 팀원 인 Eric Osgood의 설명입니다.

이것은 잠재적 인 보안 취약점을 방지하기 때문에 '의도적으로'표시되었습니다.

일부 브라우저는 URL의 해시 조각을 리디렉션 된 새 URL의 끝에 추가합니다 (새 URL 자체에 해시 조각이없는 경우).

예를 들어 example1.com이 example2.com으로 리디렉션하면 example1.com # abc로 이동하는 브라우저는 example2.com # abc로 이동하고 example1.com의 해시 조각 콘텐츠는 example2에있는 스크립트에서 액세스 할 수 있습니다 .com.

한 인증 흐름을 다른 인증 리디렉션으로 리디렉션하는 것이 가능하기 때문에 한 앱의 민감한 인증 데이터를 다른 앱에 액세스 할 수 있습니다.

이 브라우저 동작을 방지하기 위해 새 해시 조각을 리디렉션 URL에 추가하여 완화됩니다.

결과 URL의 미적 또는 클라이언트 측 동작이 문제가되는 경우 window.location.hash (또는 서버 측 리디렉션)를 사용하여 문제가되는 문자를 제거 할 수 있습니다.

출처 : https://developers.facebook.com/bugs/318390728250352/

35
Mark Murphy

왜이 작업을 수행하는지 알지 못하지만 페이지 상단의 해시를 재설정하면 문제를 해결할 수 있습니다.

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

Facebook 콜백에 대한 redirect_uri 매개 변수에 자신의 해시를 지정할 수도 있습니다. 이는 특정 상황에서 유용 할 수 있습니다. /api/account/callback#home. 다시 리디렉션 될 때 backbone.js 또는 유사 항목 (jquery 모바일에 대해 확실하지 않은 경우)을 사용하는 경우 적어도 알려진 경로에 해당하는 해시가됩니다.

9
pkiddie

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

Facebook은 프레임을 사용하며 그 안쪽에는 AJAX communication을 사용하여 모든 기능이 작동합니다. 이 경우 가장 큰 문제점은 현재 페이지 상태를 유지하는 것입니다. 내가 알기 엔, 페이스 북은 모의 앵커를 사용하기로 결정했다. 이것은 당신이 어딘가를 클릭하면, 페이지 안의 앵커로 시뮬레이션하고, AJAX 통신이 시작될 때, URL의 앵커 비트도 변경한다는 것을 의미합니다.

이 솔루션은 페이지를 다시로드하려고 할 때 일반적으로 도움이됩니다 (ENTER가 아님). F5), 브라우저가 앵커가있는 전체 URL을 Facebook 서버로 보 내기 때문입니다. 따라서 Facebook은 최신 상태 (귀하가 보는 것)를 선택하고 그로부터 계속할 수 있습니다.

콜백이 #_=_를 반환하면 페이지가 떠나기 전에 기본 상태에 있음을 의미합니다. 이 앵커는 브라우저에서 파싱되므로 걱정할 필요가 없습니다.

8
Sándor Tóth

Hashbang (/ #! /) URL을 가진 JS 프레임 워크를 사용한다면 심각한 문제가 될 수 있습니다. 모난. 실제로 Angular는 hashbang이 아닌 조각이있는 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
6
neemzy

나는이 문제가 페이스 북 AJAX와 어떻게 관련이 있는지 보지 못했다. 사실이 문제는 JavaScript가 비활성화되고 순전히 리디렉션 기반 로그인을 사용하는 경우에도 발생합니다.

페이스 북과의 교환 예 :

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#_  

나에게도 파이어 폭스에서만 일어난다.

5
Sebastian Tusk

내 리디렉션 페이지에 추가하면 문제가 해결되었습니다 ...

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

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

Vue-router를 사용하는 경우 경로 목록에 추가 할 수 있습니다.

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

페이스 북이 세션 리다이렉션을 어떻게 처리하는지 최근에 변화가 도입되었습니다. 공지 사항에 대한 이번 주 Operation Developer Love 블로그 게시물의 "세션 리디렉션 동작 변경"을 참조하십시오.

2
Dhiren Patel

나를 위해, 나는 #_=_ 없애 다른 페이지로 JavaScript 리디렉션을 확인하십시오. 아래 아이디어는 효과가 있습니다. :)

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

나는 이것을 사용하여 '#'기호도 삭제했다.

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

나는이 회신이 늦었다 고 알고있다. 그러나 당신이 passportjs를 사용하고 있다면, 이것을보고 싶어 할 것이다.

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

나는이 미들웨어를 작성하여 서버 인스턴스를 표현하기 위해이 애플리케이션을 적용했다. 원래 URL은 "#_=_"가 없다. 서버 인스턴스에 passport 인스턴스를 미들웨어로 적용 할 때처럼 보이지만 그 문자는 사용하지 않지만 브라우저의 주소 표시 줄에서만 볼 수 있습니다.

1
Krishna

Backbone.js를 사용하여 저에게 도움이되는 해결 방법은 Facebook에 전달 된 리디렉션 URL의 끝에 "#"을 추가하는 것입니다. Facebook은 제공된 조각을 유지하고 자체 "_ = _"을 추가하지 않습니다.

돌아 오면 백본은 "# /"부분을 제거합니다. AngularJS의 경우 "#!" 반환 URL로 이동해야합니다.

리디렉션 URL에도 조각 식별자가없는 경우 원래 URL의 조각 식별자는 대부분의 브라우저에서 리디렉션 할 때 보존됩니다 (HTTP 상태 코드 300, 301, 302 및 303을 통해). 이것은 권장 동작 인 것 같습니다 .

사용자를 다른 곳으로 리디렉션하는 처리기 스크립트를 사용하는 경우 여기에 리디렉션 URL에 "#"을 추가하여 조각 식별자를 빈 문자열로 바꿀 수 있습니다.

1
Ivo Smits

PHP SDK 사용자의 경우

전달하기 전에 여분의 부품을 제거하여 문제를 해결했습니다.

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

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 ), 라우트 일치에 관여하지 않습니다.

0
rcomblen

이렇게하면 URL에 첨부 된 문자가 제거됩니다.

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