File indexing completed on 2024-12-22 05:36:18
0001 <?php 0002 /** 0003 * Copyright 2011 Facebook, Inc. 0004 * 0005 * Licensed under the Apache License, Version 2.0 (the "License"); you may 0006 * not use this file except in compliance with the License. You may obtain 0007 * a copy of the License at 0008 * 0009 * http://www.apache.org/licenses/LICENSE-2.0 0010 * 0011 * Unless required by applicable law or agreed to in writing, software 0012 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 0013 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 0014 * License for the specific language governing permissions and limitations 0015 * under the License. 0016 */ 0017 0018 require_once "base_facebook.php"; 0019 0020 /** 0021 * Extends the BaseFacebook class with the intent of using 0022 * PHP sessions to store user ids and access tokens. 0023 */ 0024 class Facebook extends BaseFacebook 0025 { 0026 const FBSS_COOKIE_NAME = 'fbss'; 0027 0028 // We can set this to a high number because the main session 0029 // expiration will trump this. 0030 const FBSS_COOKIE_EXPIRE = 31556926; // 1 year 0031 0032 // Stores the shared session ID if one is set. 0033 protected $sharedSessionID; 0034 0035 /** 0036 * Identical to the parent constructor, except that 0037 * we start a PHP session to store the user ID and 0038 * access token if during the course of execution 0039 * we discover them. 0040 * 0041 * @param Array $config the application configuration. Additionally 0042 * accepts "sharedSession" as a boolean to turn on a secondary 0043 * cookie for environments with a shared session (that is, your app 0044 * shares the domain with other apps). 0045 * @see BaseFacebook::__construct in facebook.php 0046 */ 0047 public function __construct($config) { 0048 if (!session_id()) { 0049 session_start(); 0050 } 0051 parent::__construct($config); 0052 if (!empty($config['sharedSession'])) { 0053 $this->initSharedSession(); 0054 } 0055 } 0056 0057 protected static $kSupportedKeys = 0058 array('state', 'code', 'access_token', 'user_id'); 0059 0060 protected function initSharedSession() { 0061 $cookie_name = $this->getSharedSessionCookieName(); 0062 if (isset($_COOKIE[$cookie_name])) { 0063 $data = $this->parseSignedRequest($_COOKIE[$cookie_name]); 0064 if ($data && !empty($data['domain']) && 0065 self::isAllowedDomain($this->getHttpHost(), $data['domain'])) { 0066 // good case 0067 $this->sharedSessionID = $data['id']; 0068 return; 0069 } 0070 // ignoring potentially unreachable data 0071 } 0072 // evil/corrupt/missing case 0073 $base_domain = $this->getBaseDomain(); 0074 $this->sharedSessionID = md5(uniqid(mt_rand(), true)); 0075 $cookie_value = $this->makeSignedRequest( 0076 array( 0077 'domain' => $base_domain, 0078 'id' => $this->sharedSessionID, 0079 ) 0080 ); 0081 $_COOKIE[$cookie_name] = $cookie_value; 0082 if (!headers_sent()) { 0083 $expire = time() + self::FBSS_COOKIE_EXPIRE; 0084 setcookie($cookie_name, $cookie_value, $expire, '/', '.'.$base_domain); 0085 } else { 0086 // @codeCoverageIgnoreStart 0087 self::errorLog( 0088 'Shared session ID cookie could not be set! You must ensure you '. 0089 'create the Facebook instance before headers have been sent. This '. 0090 'will cause authentication issues after the first request.' 0091 ); 0092 // @codeCoverageIgnoreEnd 0093 } 0094 } 0095 0096 /** 0097 * Provides the implementations of the inherited abstract 0098 * methods. The implementation uses PHP sessions to maintain 0099 * a store for authorization codes, user ids, CSRF states, and 0100 * access tokens. 0101 */ 0102 protected function setPersistentData($key, $value) { 0103 if (!in_array($key, self::$kSupportedKeys)) { 0104 self::errorLog('Unsupported key passed to setPersistentData.'); 0105 return; 0106 } 0107 0108 $session_var_name = $this->constructSessionVariableName($key); 0109 $_SESSION[$session_var_name] = $value; 0110 } 0111 0112 protected function getPersistentData($key, $default = false) { 0113 if (!in_array($key, self::$kSupportedKeys)) { 0114 self::errorLog('Unsupported key passed to getPersistentData.'); 0115 return $default; 0116 } 0117 0118 $session_var_name = $this->constructSessionVariableName($key); 0119 return isset($_SESSION[$session_var_name]) ? 0120 $_SESSION[$session_var_name] : $default; 0121 } 0122 0123 protected function clearPersistentData($key) { 0124 if (!in_array($key, self::$kSupportedKeys)) { 0125 self::errorLog('Unsupported key passed to clearPersistentData.'); 0126 return; 0127 } 0128 0129 $session_var_name = $this->constructSessionVariableName($key); 0130 unset($_SESSION[$session_var_name]); 0131 } 0132 0133 protected function clearAllPersistentData() { 0134 foreach (self::$kSupportedKeys as $key) { 0135 $this->clearPersistentData($key); 0136 } 0137 if ($this->sharedSessionID) { 0138 $this->deleteSharedSessionCookie(); 0139 } 0140 } 0141 0142 protected function deleteSharedSessionCookie() { 0143 $cookie_name = $this->getSharedSessionCookieName(); 0144 unset($_COOKIE[$cookie_name]); 0145 $base_domain = $this->getBaseDomain(); 0146 setcookie($cookie_name, '', 1, '/', '.'.$base_domain); 0147 } 0148 0149 protected function getSharedSessionCookieName() { 0150 return self::FBSS_COOKIE_NAME . '_' . $this->getAppId(); 0151 } 0152 0153 protected function constructSessionVariableName($key) { 0154 $parts = array('fb', $this->getAppId(), $key); 0155 if ($this->sharedSessionID) { 0156 array_unshift($parts, $this->sharedSessionID); 0157 } 0158 return implode('_', $parts); 0159 } 0160 }