2013-01-05 1 views
6

PHP SDK (v 3.2.2)를 사용하여 Facebook 세션이 손실 된 것처럼 보입니다 ($ user = 0). JS SDK는 Facebook 세션을 복구하기 위해 내 페이지를 다시로드해야합니다. 이 문제는 지금 발생하고 때로는 Facebook 세션이 손실되는 경우가 있습니다. 때로는 제대로 작동합니다.페이스 북 PHP SDK 세션 분실, JS SDK 새로 고침이 필요함

session_start(); 

// Run Facebook API 
$facebook = new Facebook(array(
    'appId' => $config['facebook']['id'], 
    'secret' => $config['facebook']['secret'] 
)); 

// Fetch user 
$user = $facebook->getUser(); 
if($user) { 
    try { 
    // Just to be sure, add access token to each request 
    $user['access_token'] = $facebook->getAccessToken();  

    // Fetch user details 
    $user = $facebook->api('/me?access_token='.$user['access_token']);   
    } 
    catch (FacebookApiException $e) { 
    error_log($e); 
    $user = null; 
    } 
} 

주된 문제는 $ user = $ facebook-> getUser(); 그러나 사용자가 실제로 연결되면 JS SDK는 auth.login 이벤트를 감지하고 페이지를 다시로드합니다. auth.authResponseChange 이벤트가 매 초마다 계속 실행되므로 auth.login을 사용합니다. 이제 $ user = $ facebook-> getUser(); 사용자의 uid를 반환합니다. 페이스 북 개발자에서

window.fbAsyncInit = function() { 
    FB.init({ 
    appId : appId, 
    channelUrl : '//domain.com/signon/channel.php', 
    status  : true, 
    cookie  : true, 
    xfbml  : true 
    }); 
    FB.Event.subscribe('auth.login', function(response) { 
    location.reload(); 
    }); 
}; 

나는 앱 도메인 (domain.com) 및 사이트 URL ( http://domain.com/)을 정의했다. 이미 슬래시가 있거나없는 사이트 URL을 시도했지만 문제가 해결되지 않았습니다.

무슨 일이 일어나고 있는지, 어떤 이유로 페이스 북 PHP SDK가 사용자의 세션을 즉시 감지하지 못하고 사용자 세션을 잃어버린 채로 다시로드해야하는지에 대한 아이디어가 있습니까? 이 문제는 실제로 나쁜 UX를 일으 킵니다.

고맙습니다. 로빈

답변

5

요즘 같은 문제가 건너 왔어요

, 5mins 후 정도 활동의 당신이 다시로드 할 경우, 세션이 지속되지 않는 것 같다. 때로는 효과가 있고 때로는 그렇지 않습니다.

내가 지난 주에 대해 위해 그것으로 찾아 봤는데, 내가 생각할 수있는 유일한 솔루션이있는 페이지를 다시로드를 수행 할 JS SDK를 사용하는 것이었다 :

FB.Event.subscribe('auth.login', function(response) { 
     window.location.reload(); 
    }); 

하지만 동의, 그건 UX 측면에서 매우 우아한 솔루션은 아닙니다. 당신은 (나를 위해하지 않았다)에 PHP SDK에서 cookie PARAM, 그리고 JS의 SDK에서의 OAuth PARAM을 통과하고, 그 작동하는지 확인해야합니다

$facebook = new Facebook(array(
    'appId' => $config['facebook']['id'], 
    'secret' => $config['facebook']['secret'], 
    'cookie' => true 
)); 

FB.init({ 
    appId : appId, 
    channelUrl : '//domain.com/signon/channel.php', 
    status  : true, 
    cookie  : true, 
    xfbml  : true, 
    oauth  : true 
    }); 

을 낯선 사람조차도 나는 Github에서 latest PHP SDK을 다시 다운로드하여 샌드 박스 환경 (Apache, PHP 5.4)에 업로드했습니다. JS SDK를 사용하여 예제를 그대로 실행했고 동일한 문제가 있습니다!

위의 내용이 겨자를 자르지 않는다면 몇 가지 제안 사항이 있습니다.

, base_facebook.php 주위 파고의 비트를 수행 한 후,

$facebook->getAccessToken(); 그러나 당신에게 더 좋은 $user 경우 0을 반환 할 것입니다 통과, 조금 첫째

를 SDK를 UP 방법 변경 나는 getCode()이라는 메서드가 실제로 $_REQUEST을 사용하여 쿼리 매개 변수에서 인증 코드를 검색하는 것으로 나타났습니다.PHP 매뉴얼에서

는 $ _REQUEST는

기본적으로 $ _GET, $ _POST와 $ _COOKIE의 내용을 포함 연관 배열입니다.

하지만

은 $ _ POST 또는 $ _COOKIE, $ _GET 매우 다르다.

설정에 따라 약간의 버그가있을 수 있습니다. 그래서 그 대신, 다음과 같이 보이는 base_facebook.php의 기능 getCode()을 찾을 :

protected function getCode() { 
if (isset($_REQUEST['code'])) { 
    if ($this->state !== null && 
      isset($_REQUEST['state']) && 
      $this->state === $_REQUEST['state']) { 

     // CSRF state has done its job, so clear it 
     $this->state = null; 
     $this->clearPersistentData('state'); 
     return $_REQUEST['code']; 
    } else { 
     self::errorLog('CSRF state token does not match one provided.'); 
     return false; 
    } 
} 

return false; 
} 

를 새로운 배열/변수에 쿼리를 병합과 같이 array_merge()를 사용하여 $_GET, $_POST & $_COOKIE 배열을 포함하는 (의는 $code_array를 부르 자) :

$code_array = array_merge($_GET,$_POST,$_COOKIE); 

최종 결과는 해당 요청의 모든 데이터가 들어있는 배열입니다. 은이 (희망) 멋지게 일을해야 즉

\\replace $_REQUEST with $code_array; 
if (isset($code_array['code'])) { 
if ($this->state !== null && 
     isset($code_array['state']) && 
     $this->state === $code_array['state']) { //...and so on for the rest 

, 진행하고 함수 내부 $code_array$_REQUEST를 교체합니다.

선택 사양 - 액세스 토큰 수명 연장

이것은 선택 사항이지만, 어쨌든 그것을 포함되어 있습니다. 대부분의 새 앱은 이미 오래 동안 액세스 토큰을 보유하고있을 것입니다. 다만, $facebook->setExtendedAccessToken(); 메서드를 사용하여 기존 액세스 토큰을 변환 할 수 있습니다.

참고 : 당신은 당신이 실제로 getAccessToken() 방법으로 액세스 토큰을 얻기 전에 $facebook->setExtendedAccessToken();를 호출해야합니다.

지금, 당신의 코드를 사용하여 당신은

$user = $facebook->getUser(); 
    if($user) { 
    try { 
    // Just to be sure, add access token to each request 
    $facebook->setExtendedAccessToken(); 
    $access_token = $facebook->getAccessToken(); 
    // Fetch user details 
    $user = $facebook->api('/me?access_token='.$access_token); 
    } 
//and so on.. 

결론이 $ _GET에 $ _REQUEST 속보

은 $이 _ POST & $ _COOKIE가 (이 포함되어 있지만 기본적으로 세 가지 모두)에 보이는 것 별다른 문제없이 SDK에서 설정 한 쿠키를 가져올 수 있는지 확인하십시오. 도대체 내가 진짜로 100 % 확실하지 않기 때문에 나는 말한다.

나는 내 문제를 해결하기 위해 위의 방법을 사용했기 때문에이 문제에 대해 너무 많은 수면을 잃어 버렸고 실행 가능한 솔루션을 찾지 못해 일부 지식을 공유하기를 바라고 있습니다.

희망이 도움이됩니다.

편집 : 내가

$user_profile = $facebook->api('/'.$user.'?access_token='.$access_token); 

$user_profile = $facebook->api('/me'); 

에서 나는 또한 한 뭔가를 API 요청을했다 변화, 얘기를 깜빡 했네요, 그것은 차이를했다. :)

+0

'$ facebook-> setExtendedAccessToken();'을 호출하면 감사합니다. – Eldar

+0

/widgets에 root 및 iframe 위젯에 사이트가있는 앱이 있습니다. 기본 페이스 북의 변경 외에도/widgets에 iframe 위젯을위한 새로운 앱을 만들어야했습니다. 이제 루트 도메인의 세션은 괜찮은 것 같습니다. –

+0

나는 그것을 되 돌린다. 세션은 괜찮지 만, 페이지가 몇 분 동안 유휴 상태가 되더라도 사용자는 여전히 0을 반환한다. –

0

페이스 북 PHP SDK가 아약스가 아니며 PHP 페이지를 사용하고 있고 서버가 유효한 세션을 다시 읽으려는 페이스 북의 인증 프로세스보다 빠르게로드되기 때문일 수 있습니다. 페이스 북 PHP SDK가 요구하는 것은 애플 리케이션으로부터 세션 유효성 검증시 페이지를 새로 고치는 것이다. 이것은 Facebook Javascript SDK에 내장되어야하지만 그렇지 않은 것처럼 보인다.