Facebook 콜백에서 #_=_
해시 밑줄을 반환 URL에 추가하기 시작했습니다.
아무도 이유를 알고 있습니까? 해결 방법이 무엇입니까?
#_=_
당신이 할 경우에도 다음 장소에 Response.Redirect
당신이 실제로하고 싶은 곳으로, 브라우저는 해시를 유지하는 이유입니다, 아래 제안 된 클라이언트 측 해결 방법 만 작동합니다.
Facebook 콜백에서 #_=_
해시 밑줄을 반환 URL에 추가하기 시작했습니다.
아무도 이유를 알고 있습니까? 해결 방법이 무엇입니까?
#_=_
당신이 할 경우에도 다음 장소에 Response.Redirect
당신이 실제로하고 싶은 곳으로, 브라우저는 해시를 유지하는 이유입니다, 아래 제안 된 클라이언트 측 해결 방법 만 작동합니다.
답변:
Facebook의 플랫폼 업데이트 를 통해 :
세션 리디렉션 동작 변경
이번 주에이 필드를 비워두면 redirect_uri에 조각 # ____ = ____을 추가하기 시작했습니다. 앱이이 동작을 처리 할 수 있는지 확인하십시오.
이를 방지하려면 로그인 URL 요청에서 redirect_uri를 다음과 같이 설정하십시오 (Facebook php-sdk 사용).
$facebook->getLoginUrl(array('redirect_uri' => $_SERVER['SCRIPT_URI'],'scope' => 'user_about_me'));
최신 정보
위의 내용은 설명서 에서이 문제를 해결하기위한 내용과 동일합니다. 그러나 Facebook의 문서화 된 솔루션이 작동하지 않습니다. Facebook 플랫폼 업데이트 블로그 게시물 에 의견을 남기고이 버그 에 따라 더 나은 답변을 얻으 십시오 . 그때까지이 문제를 해결하려면 헤드 태그에 다음을 추가하십시오.
<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>
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 = "";
}
}
단계별 :
fragment
is 인 경우에만 코드 블록으로 들어갑니다 #_=_
.window.replaceState
메소드를 지원하는지 확인하십시오 .
#
첫 번째 부분 만 분리하여 가져 와서 URL을 정리하십시오 .history
깨끗한 URL과 현재 페이지 상태를 바꿀 수 있습니다. 새 항목을 만들지 않고 현재 기록 항목을 수정합니다. 이것이 의미하는 바는 뒤로 및 앞으로 버튼이 원하는대로 작동한다는 것입니다. ;-)#_-_
입니다.에 대해 자세히 알아보십시오 history.replaceState
.
에 대해 자세히 알아보십시오 window.location
.
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
}
})
e
.
이것은 보안상의 이유로 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 (또는 사용자 자신의 서버 측 리디렉션)를 사용하여 문제가있는 문자를 제거 할 수 있습니다.
왜 이런 일을하는지 확실하지 않지만 페이지 상단에서 해시를 재설정하여이 문제를 해결할 수 있습니다.
if (window.location.hash == "#_=_")
window.location.hash = "";
Facebook은 프레임을 사용하며 그 내부는 AJAX 통신을 사용하여 작동합니다. 이 경우 가장 큰 문제는 현재 페이지 상태를 유지하는 것입니다. 내가 아는 한, Facebook은 시뮬레이션 앵커를 사용하기로 결정했습니다. 즉, 어딘가에서 클릭하면 페이지 내부의 앵커로 시뮬레이션하고 AJAX 통신이 시작되면 URL의 앵커 비트도 변경됩니다.
F5브라우저가 앵커와 함께 전체 URL을 Facebook 서버로 전송하기 때문에이 솔루션은 일반적으로 페이지를 다시로드하려고 할 때 (ENTER가 아닌을 누르는 경우 ) 도움이됩니다 . 따라서 Facebook은 최신 상태 (표시되는 내용)를 선택하여 계속 진행할 수 있습니다.
콜백이 함께 반환되면 #_=_
페이지가 페이지를 떠나기 전에 기본 상태에 있었음을 의미합니다. 이 앵커는 브라우저에 의해 구문 분석되므로 걱정할 필요가 없습니다.
특히 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>
Angular와 같이 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
이 문제가 페이스 북 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#_
나에게도 Firefox 만 있습니다.
각도 및 각도 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 ...
});
});
최근 Facebook에서 세션 리디렉션을 처리하는 방식이 변경되었습니다. 공지에 대한 이번 주 Operation Developer Love 블로그 게시물 에서 "세션 리디렉션 동작 변경"을 참조하십시오 .
나를 위해 JavaScript를 다른 페이지로 리디렉션하여 제거 #_=_
합니다. 아래 아이디어는 효과가 있습니다. :)
function redirect($url){
echo "<script>window.location.href='{$url}?{$_SERVER["QUERY_STRING"]}'</script>";
}
Backbone.js를 사용하여 나를 위해 일한 해결 방법은 Facebook에 전달 된 리디렉션 URL 끝에 "# /"를 추가하는 것이 었습니다. Facebook은 제공된 조각을 유지하고 자체 "_ = _"를 추가하지 않습니다.
돌아 오면 Backbone은 "# /"부분을 제거합니다. AngularJS의 경우 "#!"추가 반환 URL로 작동합니다.
리디렉션 URL에 조각 식별자가없는 경우 원래 URL의 조각 식별자는 대부분의 브라우저에서 리디렉션 (HTTP 상태 코드 300, 301, 302 및 303을 통해)으로 유지됩니다. 이것은 권장되는 행동 인 것 같습니다 .
사용자를 다른 곳으로 리디렉션하는 핸들러 스크립트를 사용하는 경우 여기에서 리디렉션 URL에 "#"을 추가하여 조각 식별자를 빈 문자열로 바꿀 수 있습니다.
답장이 늦었다는 것을 알고 있지만, Passportjs를 사용하고 있다면 이것을보고 싶을 것입니다.
return (req, res, next) => {
console.log(req.originalUrl);
next();
};
이 미들웨어를 작성하여 서버 인스턴스를 표현하는 데 적용했으며 원래 URL은 "#_=_"
입니다. passporJS의 인스턴스를 서버 인스턴스에 미들웨어로 적용하면 해당 문자를 사용하지 않지만 브라우저의 주소 표시 줄에서만 볼 수 있습니다.
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 참조 ) 경로 일치와 관련이 없습니다.
"# _ = _"(PHP)를 제거하는 가장 쉽고 깨끗한 솔루션 :
"header ("Location : xxx.php ");"대신 "echo ("location.href = 'xxx.php'; ");"를 사용하려면