facebook SDKのPHP版でセッションを使わない+Javascript SDKのログインを利用する

facebook SDKPHP版でセッションを使わない+Javascript SDKのログインを利用する

 古いPHP SDKの記事ではよく


$facebook = new Facebook(array(
	'appId' => $app_id,
	'secret' => $secret,
	'cookie' => true,	// 無意味
));

――のような記述がありますが、現時点のSDK3.0.1ではcookieオプションは存在しないので意味ないです。

 また、Javascript SDKを使ってログインしてcookieを渡されてもcookieのパースをしてくれません。

 仕方がないのでそのへんを便利に使えるサブクラスを作りました:


require_once "facebook.php";

class FacebookWithCookie extends Facebook
{
  protected $facebookCookie;
  public function getFacebookCookie() {
  	if (isset($this->facebookCookie)) return $this->facebookCookie;

    $app_id = $this->getAppId();
    $app_secret = $this->getApiSecret();

    $cookie_key = 'fbs_' . $app_id;
    if (!isset($_COOKIE[$cookie_key])) return $this->facebookCookie = false;

    $cookie_val = $_COOKIE[$cookie_key];
    setrawcookie($cookie_key, $cookie_val);

    $args = array();
    parse_str(trim($cookie_val, '\\"'), $args);
    ksort($args);
    $payload = '';
    foreach ($args as $key => $value) {
      if ($key != 'sig') {
        $payload .= $key . '=' . $value;
      }
    }

    if (md5($payload . $app_secret) != $args['sig']) {
      return $this->facebookCookie = false;
    }
    return $this->facebookCookie = $args;
  }
  public function getAccessToken() {
    if ($this->accessToken !== null) {
      return $this->accessToken;
    }

    $facebook_cookie = $this->getFacebookCookie();
    if (isset($facebook_cookie['access_token'])) {
      $this->setAccessToken($facebook_cookie['access_token']);
      return $this->accessToken;
    }

    return parent::getAccessToken();
  }
}

 これでログイン処理はJavascript側に任せてPHP側はCookieをチェックすることでログインの判定ができる、はず。

 でまあ、Cookieに情報が保存されてるならPHPのセッションに保存しないで欲しいなぁと思ったので、結局下記のような感じで使ってます:


require_once "base_facebook.php";

class FacebookNoSession extends BaseFacebook
{
  protected $facebookCookie;
  public function getFacebookCookie() {
  	if (isset($this->facebookCookie)) return $this->facebookCookie;

    $app_id = $this->getAppId();
    $app_secret = $this->getApiSecret();

    $cookie_key = 'fbs_' . $app_id;
    if (!isset($_COOKIE[$cookie_key])) return $this->facebookCookie = false;

    $cookie_val = $_COOKIE[$cookie_key];
    setcookie($cookie_key, $cookie_val);

    $args = array();
    parse_str(trim($cookie_val, '\\"'), $args);
    ksort($args);
    $payload = '';
    foreach ($args as $key => $value) {
      if ($key != 'sig') {
        $payload .= $key . '=' . $value;
      }
    }

    if (md5($payload . $app_secret) != $args['sig']) {
      return $this->facebookCookie = false;
    }
    return $this->facebookCookie = $args;
  }
  public function getAccessToken() {
    if ($this->accessToken !== null) {
      return $this->accessToken;
    }

    $facebook_cookie = $this->getFacebookCookie();
    if (isset($facebook_cookie['access_token'])) {
      $this->setAccessToken($facebook_cookie['access_token']);
      return $this->accessToken;
    }

    return parent::getAccessToken();
  }
  public function getUser() {
    $user = parent::getUser();
    if ($user) return $user;

    $facebook_cookie = $this->getFacebookCookie();
    if ($facebook_cookie) return $this->user = $facebook_cookie['uid'];
  }

  protected function setPersistentData($key, $value) {
  }
  protected function getPersistentData($key, $default = false) {
  }
  protected function clearPersistentData($key) {
  }
  protected function clearAllPersistentData() {
  }
}

追記(2011-09-16)

 ユーザーが取得できないケースがあったので「function getUser()」を修正(追加)しました。