initial commit
This commit is contained in:
370
app/Vendor/Facebook/Entities/AccessToken.php
vendored
Normal file
370
app/Vendor/Facebook/Entities/AccessToken.php
vendored
Normal file
@@ -0,0 +1,370 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2014 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\Entities;
|
||||
|
||||
use Facebook\FacebookRequest;
|
||||
use Facebook\FacebookRequestException;
|
||||
use Facebook\FacebookSession;
|
||||
use Facebook\GraphSessionInfo;
|
||||
|
||||
/**
|
||||
* Class AccessToken
|
||||
* @package Facebook
|
||||
*/
|
||||
class AccessToken
|
||||
{
|
||||
|
||||
/**
|
||||
* The access token.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $accessToken;
|
||||
|
||||
/**
|
||||
* A unique ID to identify a client.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $machineId;
|
||||
|
||||
/**
|
||||
* Date when token expires.
|
||||
*
|
||||
* @var \DateTime|null
|
||||
*/
|
||||
protected $expiresAt;
|
||||
|
||||
/**
|
||||
* Create a new access token entity.
|
||||
*
|
||||
* @param string $accessToken
|
||||
* @param int $expiresAt
|
||||
* @param string|null machineId
|
||||
*/
|
||||
public function __construct($accessToken, $expiresAt = 0, $machineId = null)
|
||||
{
|
||||
$this->accessToken = $accessToken;
|
||||
if ($expiresAt) {
|
||||
$this->setExpiresAtFromTimeStamp($expiresAt);
|
||||
}
|
||||
$this->machineId = $machineId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for expires_at.
|
||||
*
|
||||
* @param int $timeStamp
|
||||
*/
|
||||
protected function setExpiresAtFromTimeStamp($timeStamp)
|
||||
{
|
||||
$dt = new \DateTime();
|
||||
$dt->setTimestamp($timeStamp);
|
||||
$this->expiresAt = $dt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for expiresAt.
|
||||
*
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
public function getExpiresAt()
|
||||
{
|
||||
return $this->expiresAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter for machineId.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getMachineId()
|
||||
{
|
||||
return $this->machineId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether or not this is a long-lived token.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLongLived()
|
||||
{
|
||||
if ($this->expiresAt) {
|
||||
return $this->expiresAt->getTimestamp() > time() + (60 * 60 * 2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the validity of the access token.
|
||||
*
|
||||
* @param string|null $appId Application ID to use
|
||||
* @param string|null $appSecret App secret value to use
|
||||
* @param string|null $machineId
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isValid($appId = null, $appSecret = null, $machineId = null)
|
||||
{
|
||||
$accessTokenInfo = $this->getInfo($appId, $appSecret);
|
||||
$machineId = $machineId ?: $this->machineId;
|
||||
return static::validateAccessToken($accessTokenInfo, $appId, $machineId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the provided GraphSessionInfo object is valid,
|
||||
* throwing an exception if not. Ensures the appId matches,
|
||||
* that the machineId matches if it's being used,
|
||||
* that the token is valid and has not expired.
|
||||
*
|
||||
* @param GraphSessionInfo $tokenInfo
|
||||
* @param string|null $appId Application ID to use
|
||||
* @param string|null $machineId
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function validateAccessToken(GraphSessionInfo $tokenInfo,
|
||||
$appId = null, $machineId = null)
|
||||
{
|
||||
$targetAppId = FacebookSession::_getTargetAppId($appId);
|
||||
|
||||
$appIdIsValid = $tokenInfo->getAppId() == $targetAppId;
|
||||
$machineIdIsValid = $tokenInfo->getProperty('machine_id') == $machineId;
|
||||
$accessTokenIsValid = $tokenInfo->isValid();
|
||||
|
||||
// Not all access tokens return an expiration. E.g. an app access token.
|
||||
if ($tokenInfo->getExpiresAt() instanceof \DateTime) {
|
||||
$accessTokenIsStillAlive = $tokenInfo->getExpiresAt()->getTimestamp() >= time();
|
||||
} else {
|
||||
$accessTokenIsStillAlive = true;
|
||||
}
|
||||
|
||||
return $appIdIsValid && $machineIdIsValid && $accessTokenIsValid && $accessTokenIsStillAlive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a valid access token from a code.
|
||||
*
|
||||
* @param string $code
|
||||
* @param string|null $appId
|
||||
* @param string|null $appSecret
|
||||
* @param string|null $machineId
|
||||
*
|
||||
* @return AccessToken
|
||||
*/
|
||||
public static function getAccessTokenFromCode($code, $appId = null, $appSecret = null, $machineId = null)
|
||||
{
|
||||
$params = array(
|
||||
'code' => $code,
|
||||
'redirect_uri' => '',
|
||||
);
|
||||
|
||||
if ($machineId) {
|
||||
$params['machine_id'] = $machineId;
|
||||
}
|
||||
|
||||
return static::requestAccessToken($params, $appId, $appSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a valid code from an access token.
|
||||
*
|
||||
* @param AccessToken|string $accessToken
|
||||
* @param string|null $appId
|
||||
* @param string|null $appSecret
|
||||
*
|
||||
* @return AccessToken
|
||||
*/
|
||||
public static function getCodeFromAccessToken($accessToken, $appId = null, $appSecret = null)
|
||||
{
|
||||
$accessToken = (string) $accessToken;
|
||||
|
||||
$params = array(
|
||||
'access_token' => $accessToken,
|
||||
'redirect_uri' => '',
|
||||
);
|
||||
|
||||
return static::requestCode($params, $appId, $appSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exchanges a short lived access token with a long lived access token.
|
||||
*
|
||||
* @param string|null $appId
|
||||
* @param string|null $appSecret
|
||||
*
|
||||
* @return AccessToken
|
||||
*/
|
||||
public function extend($appId = null, $appSecret = null)
|
||||
{
|
||||
$params = array(
|
||||
'grant_type' => 'fb_exchange_token',
|
||||
'fb_exchange_token' => $this->accessToken,
|
||||
);
|
||||
|
||||
return static::requestAccessToken($params, $appId, $appSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request an access token based on a set of params.
|
||||
*
|
||||
* @param array $params
|
||||
* @param string|null $appId
|
||||
* @param string|null $appSecret
|
||||
*
|
||||
* @return AccessToken
|
||||
*
|
||||
* @throws FacebookRequestException
|
||||
*/
|
||||
public static function requestAccessToken(array $params, $appId = null, $appSecret = null)
|
||||
{
|
||||
$response = static::request('/oauth/access_token', $params, $appId, $appSecret);
|
||||
$data = $response->getResponse();
|
||||
|
||||
/**
|
||||
* @TODO fix this malarkey - getResponse() should always return an object
|
||||
* @see https://github.com/facebook/facebook-php-sdk-v4/issues/36
|
||||
*/
|
||||
if (is_array($data)) {
|
||||
if (isset($data['access_token'])) {
|
||||
$expiresAt = isset($data['expires']) ? time() + $data['expires'] : 0;
|
||||
return new static($data['access_token'], $expiresAt);
|
||||
}
|
||||
} elseif($data instanceof \stdClass) {
|
||||
if (isset($data->access_token)) {
|
||||
$expiresAt = isset($data->expires_in) ? time() + $data->expires_in : 0;
|
||||
$machineId = isset($data->machine_id) ? (string) $data->machine_id : null;
|
||||
return new static((string) $data->access_token, $expiresAt, $machineId);
|
||||
}
|
||||
}
|
||||
|
||||
throw FacebookRequestException::create(
|
||||
$response->getRawResponse(),
|
||||
$data,
|
||||
401
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request a code from a long lived access token.
|
||||
*
|
||||
* @param array $params
|
||||
* @param string|null $appId
|
||||
* @param string|null $appSecret
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws FacebookRequestException
|
||||
*/
|
||||
public static function requestCode(array $params, $appId = null, $appSecret = null)
|
||||
{
|
||||
$response = static::request('/oauth/client_code', $params, $appId, $appSecret);
|
||||
$data = $response->getResponse();
|
||||
|
||||
if (isset($data->code)) {
|
||||
return (string) $data->code;
|
||||
}
|
||||
|
||||
throw FacebookRequestException::create(
|
||||
$response->getRawResponse(),
|
||||
$data,
|
||||
401
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a request to Graph with an app access token.
|
||||
*
|
||||
* @param string $endpoint
|
||||
* @param array $params
|
||||
* @param string|null $appId
|
||||
* @param string|null $appSecret
|
||||
*
|
||||
* @return \Facebook\FacebookResponse
|
||||
*
|
||||
* @throws FacebookRequestException
|
||||
*/
|
||||
protected static function request($endpoint, array $params, $appId = null, $appSecret = null)
|
||||
{
|
||||
$targetAppId = FacebookSession::_getTargetAppId($appId);
|
||||
$targetAppSecret = FacebookSession::_getTargetAppSecret($appSecret);
|
||||
|
||||
if (!isset($params['client_id'])) {
|
||||
$params['client_id'] = $targetAppId;
|
||||
}
|
||||
if (!isset($params['client_secret'])) {
|
||||
$params['client_secret'] = $targetAppSecret;
|
||||
}
|
||||
|
||||
// The response for this endpoint is not JSON, so it must be handled
|
||||
// differently, not as a GraphObject.
|
||||
$request = new FacebookRequest(
|
||||
FacebookSession::newAppSession($targetAppId, $targetAppSecret),
|
||||
'GET',
|
||||
$endpoint,
|
||||
$params
|
||||
);
|
||||
return $request->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get more info about an access token.
|
||||
*
|
||||
* @param string|null $appId
|
||||
* @param string|null $appSecret
|
||||
*
|
||||
* @return GraphSessionInfo
|
||||
*/
|
||||
public function getInfo($appId = null, $appSecret = null)
|
||||
{
|
||||
$params = array('input_token' => $this->accessToken);
|
||||
|
||||
$request = new FacebookRequest(
|
||||
FacebookSession::newAppSession($appId, $appSecret),
|
||||
'GET',
|
||||
'/debug_token',
|
||||
$params
|
||||
);
|
||||
$response = $request->execute()->getGraphObject(GraphSessionInfo::className());
|
||||
|
||||
// Update the data on this token
|
||||
if ($response->getExpiresAt()) {
|
||||
$this->expiresAt = $response->getExpiresAt();
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the access token as a string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->accessToken;
|
||||
}
|
||||
|
||||
}
|
||||
386
app/Vendor/Facebook/Entities/SignedRequest.php
vendored
Normal file
386
app/Vendor/Facebook/Entities/SignedRequest.php
vendored
Normal file
@@ -0,0 +1,386 @@
|
||||
<?php
|
||||
/**
|
||||
* Copyright 2014 Facebook, Inc.
|
||||
*
|
||||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to
|
||||
* use, copy, modify, and distribute this software in source code or binary
|
||||
* form for use in connection with the web services and APIs provided by
|
||||
* Facebook.
|
||||
*
|
||||
* As with any software that integrates with the Facebook platform, your use
|
||||
* of this software is subject to the Facebook Developer Principles and
|
||||
* Policies [http://developers.facebook.com/policy/]. This copyright notice
|
||||
* shall be included in all copies or substantial portions of the software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
namespace Facebook\Entities;
|
||||
|
||||
use Facebook\FacebookSDKException;
|
||||
use Facebook\FacebookSession;
|
||||
|
||||
/**
|
||||
* Class SignedRequest
|
||||
* @package Facebook
|
||||
*/
|
||||
class SignedRequest
|
||||
{
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $rawSignedRequest;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $payload;
|
||||
|
||||
/**
|
||||
* Instantiate a new SignedRequest entity.
|
||||
*
|
||||
* @param string|null $rawSignedRequest The raw signed request.
|
||||
* @param string|null $state random string to prevent CSRF.
|
||||
* @param string|null $appSecret
|
||||
*/
|
||||
public function __construct($rawSignedRequest = null, $state = null, $appSecret = null)
|
||||
{
|
||||
if (!$rawSignedRequest) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->rawSignedRequest = $rawSignedRequest;
|
||||
$this->payload = static::parse($rawSignedRequest, $state, $appSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw signed request data.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getRawSignedRequest()
|
||||
{
|
||||
return $this->rawSignedRequest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parsed signed request data.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getPayload()
|
||||
{
|
||||
return $this->payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a property from the signed request data if available.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed|null $default
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function get($key, $default = null)
|
||||
{
|
||||
if (isset($this->payload[$key])) {
|
||||
return $this->payload[$key];
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns user_id from signed request data if available.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getUserId()
|
||||
{
|
||||
return $this->get('user_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for OAuth data in the payload.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasOAuthData()
|
||||
{
|
||||
return isset($this->payload['oauth_token']) || isset($this->payload['code']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a signed request from an array of data.
|
||||
*
|
||||
* @param array $payload
|
||||
* @param string|null $appSecret
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function make(array $payload, $appSecret = null)
|
||||
{
|
||||
$payload['algorithm'] = 'HMAC-SHA256';
|
||||
$payload['issued_at'] = time();
|
||||
$encodedPayload = static::base64UrlEncode(json_encode($payload));
|
||||
|
||||
$hashedSig = static::hashSignature($encodedPayload, $appSecret);
|
||||
$encodedSig = static::base64UrlEncode($hashedSig);
|
||||
|
||||
return $encodedSig.'.'.$encodedPayload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates and decodes a signed request and returns
|
||||
* the payload as an array.
|
||||
*
|
||||
* @param string $signedRequest
|
||||
* @param string|null $state
|
||||
* @param string|null $appSecret
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function parse($signedRequest, $state = null, $appSecret = null)
|
||||
{
|
||||
list($encodedSig, $encodedPayload) = static::split($signedRequest);
|
||||
|
||||
// Signature validation
|
||||
$sig = static::decodeSignature($encodedSig);
|
||||
$hashedSig = static::hashSignature($encodedPayload, $appSecret);
|
||||
static::validateSignature($hashedSig, $sig);
|
||||
|
||||
// Payload validation
|
||||
$data = static::decodePayload($encodedPayload);
|
||||
static::validateAlgorithm($data);
|
||||
if ($state) {
|
||||
static::validateCsrf($data, $state);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the format of a signed request.
|
||||
*
|
||||
* @param string $signedRequest
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public static function validateFormat($signedRequest)
|
||||
{
|
||||
if (strpos($signedRequest, '.') !== false) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new FacebookSDKException(
|
||||
'Malformed signed request.', 606
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes a raw valid signed request.
|
||||
*
|
||||
* @param string $signedRequest
|
||||
*
|
||||
* @returns array
|
||||
*/
|
||||
public static function split($signedRequest)
|
||||
{
|
||||
static::validateFormat($signedRequest);
|
||||
|
||||
return explode('.', $signedRequest, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the raw signature from a signed request.
|
||||
*
|
||||
* @param string $encodedSig
|
||||
*
|
||||
* @returns string
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public static function decodeSignature($encodedSig)
|
||||
{
|
||||
$sig = static::base64UrlDecode($encodedSig);
|
||||
|
||||
if ($sig) {
|
||||
return $sig;
|
||||
}
|
||||
|
||||
throw new FacebookSDKException(
|
||||
'Signed request has malformed encoded signature data.', 607
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes the raw payload from a signed request.
|
||||
*
|
||||
* @param string $encodedPayload
|
||||
*
|
||||
* @returns array
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public static function decodePayload($encodedPayload)
|
||||
{
|
||||
$payload = static::base64UrlDecode($encodedPayload);
|
||||
|
||||
if ($payload) {
|
||||
$payload = json_decode($payload, true);
|
||||
}
|
||||
|
||||
if (is_array($payload)) {
|
||||
return $payload;
|
||||
}
|
||||
|
||||
throw new FacebookSDKException(
|
||||
'Signed request has malformed encoded payload data.', 607
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the algorithm used in a signed request.
|
||||
*
|
||||
* @param array $data
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public static function validateAlgorithm(array $data)
|
||||
{
|
||||
if (isset($data['algorithm']) && $data['algorithm'] === 'HMAC-SHA256') {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new FacebookSDKException(
|
||||
'Signed request is using the wrong algorithm.', 605
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashes the signature used in a signed request.
|
||||
*
|
||||
* @param string $encodedData
|
||||
* @param string|null $appSecret
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public static function hashSignature($encodedData, $appSecret = null)
|
||||
{
|
||||
$hashedSig = hash_hmac(
|
||||
'sha256', $encodedData, FacebookSession::_getTargetAppSecret($appSecret), $raw_output = true
|
||||
);
|
||||
|
||||
if ($hashedSig) {
|
||||
return $hashedSig;
|
||||
}
|
||||
|
||||
throw new FacebookSDKException(
|
||||
'Unable to hash signature from encoded payload data.', 602
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the signature used in a signed request.
|
||||
*
|
||||
* @param string $hashedSig
|
||||
* @param string $sig
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public static function validateSignature($hashedSig, $sig)
|
||||
{
|
||||
if (mb_strlen($hashedSig) === mb_strlen($sig)) {
|
||||
$validate = 0;
|
||||
for ($i = 0; $i < mb_strlen($sig); $i++) {
|
||||
$validate |= ord($hashedSig[$i]) ^ ord($sig[$i]);
|
||||
}
|
||||
if ($validate === 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new FacebookSDKException(
|
||||
'Signed request has an invalid signature.', 602
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a signed request against CSRF.
|
||||
*
|
||||
* @param array $data
|
||||
* @param string $state
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public static function validateCsrf(array $data, $state)
|
||||
{
|
||||
if (isset($data['state']) && $data['state'] === $state) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new FacebookSDKException(
|
||||
'Signed request did not pass CSRF validation.', 604
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Base64 decoding which replaces characters:
|
||||
* + instead of -
|
||||
* / instead of _
|
||||
* @link http://en.wikipedia.org/wiki/Base64#URL_applications
|
||||
*
|
||||
* @param string $input base64 url encoded input
|
||||
*
|
||||
* @return string decoded string
|
||||
*/
|
||||
public static function base64UrlDecode($input)
|
||||
{
|
||||
$urlDecodedBase64 = strtr($input, '-_', '+/');
|
||||
static::validateBase64($urlDecodedBase64);
|
||||
return base64_decode($urlDecodedBase64);
|
||||
}
|
||||
|
||||
/**
|
||||
* Base64 encoding which replaces characters:
|
||||
* + instead of -
|
||||
* / instead of _
|
||||
* @link http://en.wikipedia.org/wiki/Base64#URL_applications
|
||||
*
|
||||
* @param string $input string to encode
|
||||
*
|
||||
* @return string base64 url encoded input
|
||||
*/
|
||||
public static function base64UrlEncode($input)
|
||||
{
|
||||
return strtr(base64_encode($input), '+/', '-_');
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a base64 string.
|
||||
*
|
||||
* @param string $input base64 value to validate
|
||||
*
|
||||
* @throws FacebookSDKException
|
||||
*/
|
||||
public static function validateBase64($input)
|
||||
{
|
||||
$pattern = '/^[a-zA-Z0-9\/\r\n+]*={0,2}$/';
|
||||
if (preg_match($pattern, $input)) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new FacebookSDKException(
|
||||
'Signed request contains malformed base64 encoding.', 608
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user