/**
  * Check if the request signature corresponds to the one calculated for the request.
  *
  * @param string $signatureBase
  *        	This is a description
  * @param string $consumerSecret
  * @param string $tokenSecret
  * @param string $signature
  *        	from the request, still URL encoded
  * @return boolean True if signature is valid
  */
 public function verify($signatureBase, $consumerSecret, $tokenSecret, $signature)
 {
     $a = Rfc3986::urlDecode($signature);
     $b = Rfc3986::urlDecode($this->make($signatureBase, $consumerSecret, $tokenSecret));
     // We have to compare the decoded values
     // $valA = base64_decode($a);
     // $valB = base64_decode($b);
     // Crude binary comparison
     // return (rawurlencode($a) === rawurlencode($b));
     return rawurlencode($a) === rawurlencode($b);
 }
 /**
  * Exchange a request token for an access token
  *
  * @param boolean $bypassNonce
  *        	Whether bypass nonce check or not
  * @return array The new access token
  */
 public function accessToken($bypassNonce = false)
 {
     $result = $this->verify('request', $bypassNonce);
     // Optional TTL
     $options = array();
     $ttl = $this->getParam(self::XOAUTH_TOKEN_TTL, true);
     if ($ttl) {
         $options['token_ttl'] = $ttl;
     }
     $verifier = $this->getParam(self::OAUTH_VERIFIER, true);
     if ($verifier) {
         $options['verifier'] = $verifier;
     }
     $options['callback_url'] = isset($result['callback_url']) ? $result['callback_url'] : null;
     $options['referer_url'] = isset($result['referer_url']) ? $result['referer_url'] : null;
     // Exchange request token for an access token
     if (!isset($this->storages['request_token'])) {
         throw new \RuntimeException('You must supply a storage object implementing ' . $this->storageMap['request_token']);
     }
     if (!isset($this->storages['access_token'])) {
         throw new \RuntimeException('You must supply a storage object implementing ' . $this->storageMap['access_token']);
     }
     // Should have a transaction here?
     $accessToken = $this->storages['access_token']->createAccessToken($result['consumer_key'], $result['username'], $options);
     if (!$accessToken) {
         throw new \RuntimeException('Cannot create new access token for ' . json_encode($result));
     }
     // Delete request token here
     $this->storages['access_token']->deleteRequestToken($result['token']);
     $data = [];
     $data[self::OAUTH_TOKEN] = Rfc3986::urlEncode($accessToken['token']);
     $data[self::OAUTH_TOKEN_SECRET] = Rfc3986::urlEncode($accessToken['token_secret']);
     $data[self::OAUTH_CALLBACK_CONFIRMED] = 1;
     if (!empty($accessToken['expires_at']) && is_numeric($accessToken['expires_at'])) {
         $expiresAt = Carbon::createFromTimestamp(intval($accessToken['expires_at']));
         $data[self::XOAUTH_TOKEN_TTL] = $expiresAt->diffInSeconds();
     }
     return $data;
 }