Ejemplo n.º 1
0
 /**
  * Decodes a JWT string into a PHP object.
  *
  * @param string            $jwt            The JWT
  * @param string|array|null $key            The key, or map of keys.
  *                                          If the algorithm used is asymmetric, this is the public key
  * @param array             $allowed_algs   List of supported verification algorithms
  *                                          Supported algorithms are 'HS256', 'HS384', 'HS512' and 'RS256'
  *
  * @return object The JWT's payload as a PHP object
  *
  * @throws DomainException              Algorithm was not provided
  * @throws UnexpectedValueException     Provided JWT was invalid
  * @throws SignatureInvalidException    Provided JWT was invalid because the signature verification failed
  * @throws BeforeValidException         Provided JWT is trying to be used before it's eligible as defined by 'nbf'
  * @throws BeforeValidException         Provided JWT is trying to be used before it's been created as defined by 'iat'
  * @throws ExpiredException             Provided JWT has since expired, as defined by the 'exp' claim
  *
  * @uses jsonDecode
  * @uses urlsafeB64Decode
  */
 public static function decode($jwt, $key, $allowed_algs = array())
 {
     if (empty($key)) {
         throw new InvalidArgumentException('Key may not be empty');
     }
     $tks = explode('.', $jwt);
     if (count($tks) != 3) {
         throw new UnexpectedValueException('Wrong number of segments');
     }
     list($headb64, $bodyb64, $cryptob64) = $tks;
     if (null === ($header = JWT::jsonDecode(JWT::urlsafeB64Decode($headb64)))) {
         throw new UnexpectedValueException('Invalid header encoding');
     }
     if (null === ($payload = JWT::jsonDecode(JWT::urlsafeB64Decode($bodyb64)))) {
         throw new UnexpectedValueException('Invalid claims encoding');
     }
     $sig = JWT::urlsafeB64Decode($cryptob64);
     if (empty($header->alg)) {
         throw new DomainException('Empty algorithm');
     }
     if (empty(self::$supported_algs[$header->alg])) {
         throw new DomainException('Algorithm not supported');
     }
     if (!is_array($allowed_algs) || !in_array($header->alg, $allowed_algs)) {
         throw new DomainException('Algorithm not allowed');
     }
     if (is_array($key) || $key instanceof \ArrayAccess) {
         if (isset($header->kid)) {
             $key = $key[$header->kid];
         } else {
             throw new DomainException('"kid" empty, unable to lookup correct key');
         }
     }
     // Check the signature
     if (!JWT::verify("{$headb64}.{$bodyb64}", $sig, $key, $header->alg)) {
         throw new SignatureInvalidException('Signature verification failed');
     }
     // Check if the nbf if it is defined. This is the time that the
     // token can actually be used. If it's not yet that time, abort.
     if (isset($payload->nbf) && $payload->nbf > time() + self::$leeway) {
         throw new BeforeValidException('Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->nbf));
     }
     // Check that this token has been created before 'now'. This prevents
     // using tokens that have been created for later use (and haven't
     // correctly used the nbf claim).
     if (isset($payload->iat) && $payload->iat > time() + self::$leeway) {
         throw new BeforeValidException('Cannot handle token prior to ' . date(DateTime::ISO8601, $payload->iat));
     }
     // Check if refresh token return access t
     if (isset($payload->ref)) {
         header('Content-Type:application/json');
         $table = TableRegistry::get('AuthToken');
         $authToken = $table->find('all')->where(['user_id' => $payload->sub, 'refresh_token' => $jwt])->first();
         if ($authToken) {
             $expire = !is_null(Configure::read('AuthToken.expire')) ? Configure::read('AuthToken.expire') : 3600;
             $access_token = JWT::encode(['sub' => $authToken['user_id'], 'exp' => time() + $expire], Security::salt());
             $refresh_token = JWT::encode(['sub' => $authToken['user_id'], 'ref' => time()], Security::salt());
             $authToken->access_token = $access_token;
             $authToken->refresh_token = $refresh_token;
             $table->save($authToken);
             echo json_encode(['success' => true, 'data' => ['access_token' => $access_token, 'refresh_token' => $refresh_token]]);
         } else {
             echo json_encode(['success' => false, 'refresh_token_expired' => true]);
         }
         exit;
     }
     // Check if this token has expired.
     if (isset($payload->exp) && time() - self::$leeway >= $payload->exp) {
         //throw new ExpiredException('Expired token');
         header('Content-Type:application/json');
         echo json_encode(['success' => false, 'access_token_expired' => true]);
         exit;
     }
     return $payload;
 }