src/SimpleJWT/JWT.php
/**
     * Decodes a serialised JWT.
     *
     * @param string $token the serialised JWT
     * @param \SimpleJWT\Keys\KeySet $keys the key set containing the key to verify the
     * JWT's signature
     * @param string $expected_alg the expected value of the `alg` parameter, which
     * should be agreed between the parties out-of-band
     * @param string $kid the ID of the key to use to verify the signature. If null, this
     * is automatically retrieved
     * @param bool|array $skip_validation an array of headers or claims that
     * should be ignored as part of the validation process (e.g. if expired tokens
     * are to be accepted), or false if all validation
     * is to be performed.
     * @return JWT the decoded JWT
     * @throws InvalidTokenException if the token is invalid for any reason
     */
Decodes a serialised JWT.
@param string $token the serialised JWT
@param \SimpleJWT\Keys\KeySet $keys the key set containing the key to verify the
JWT's signature
@param string $expected_alg the expected value of the `alg` parameter, which
should be agreed between the parties out-of-band
@param string $kid the ID of the key to use to verify the signature. If null, this
is automatically retrieved
@param bool|array $skip_validation an array of headers or claims that
should be ignored as part of the validation process , or false if all validation
is to be performed.
@return JWT the decoded JWT
@throws InvalidTokenException if the token is invalid for any reason
Decodes a serialised JWT . @param string $token the serialised JWT @param \ SimpleJWT \ Keys \ KeySet $keys the key set containing the key to verify the JWT ' s signature @param string $expected_alg the expected value of the ` alg ` parameter which should be agreed between the parties out - of - band @param string $kid the ID of the key to use to verify the signature . If null this is automatically retrieved @param bool|array $skip_validation an array of headers or claims that should be ignored as part of the validation process or false if all validation is to be performed . @return JWT the decoded JWT @throws InvalidTokenException if the token is invalid for any reason
public static function decode($token, $keys, $expected_alg, $kid = null, $skip_validation = []) {
        if ($skip_validation === false) $skip_validation = [];
        $deserialised = self::deserialise($token);
        $claims = $deserialised['claims'];
        if (count($deserialised['signatures']) > 1) {
            foreach ($deserialised['signatures'] as $signature_obj) {
                if (isset($signature_obj['header']['kid'])) {
                    $target_kid = $signature_obj['header']['kid'];
                    if (($target_kid == $kid) || ($keys->getById($target_kid) != null)) {
                        $headers = $signature_obj['headers'];
                        $signing_input = $signature_obj['signing_input'];
                        $signature = $signature_obj['signature'];
                        break;
                    }
                }
                throw new InvalidTokenException('Cannot find verifiable signature', InvalidTokenException::TOKEN_PARSE_ERROR);
            }
        } else {
            $headers = $deserialised['signatures'][0]['headers'];
            $signing_input = $deserialised['signatures'][0]['signing_input'];
            $signature = $deserialised['signatures'][0]['signature'];
        }
        if (isset($headers['crit'])) {
            foreach ($headers['crit'] as $critical) {
                if (!in_array($critical, ['nbf', 'exp', 'alg', 'kid'])) {
                    throw new InvalidTokenException('Critical header not supported: ' . $critical, InvalidTokenException::UNSUPPORTED_ERROR);
                }
            }
        }
        if ($headers['alg'] != $expected_alg) throw new InvalidTokenException('Unexpected algorithm', InvalidTokenException::SIGNATURE_VERIFICATION_ERROR);
        $signer = AlgorithmFactory::create($expected_alg);
        try {
            if (isset($headers['kid'])) $kid = $headers['kid'];
            $result = $signer->verify($signature, $signing_input, $keys, $kid);
        } catch (KeyException $e) {
            throw new InvalidTokenException($e->getMessage(), InvalidTokenException::SIGNATURE_VERIFICATION_ERROR, $e);
        } catch (CryptException $e) {
            throw new InvalidTokenException($e->getMessage(), InvalidTokenException::SIGNATURE_VERIFICATION_ERROR, $e);
        }
        if (!$result) throw new InvalidTokenException('Incorrect signature', InvalidTokenException::SIGNATURE_VERIFICATION_ERROR);
        $time = time();
        if (isset($claims['nbf']) && !in_array('nbf', $skip_validation)) {
            if ($time < $claims['nbf'] - self::$TIME_ALLOWANCE) throw new InvalidTokenException('Too early due to nbf claim', InvalidTokenException::TOO_EARLY_ERROR, null, $claims['nbf']);
        }
        if (isset($claims['exp']) && !in_array('exp', $skip_validation)) {
            if ($time > $claims['exp'] + self::$TIME_ALLOWANCE) throw new InvalidTokenException('Too late due to exp claim', InvalidTokenException::TOO_LATE_ERROR, null, $claims['exp']);
        }
        return new JWT($headers, $claims);
    }
public static function decode ( $ token , $ keys , $ expected_alg , $ kid = null , $ skip_validation = [ ] ) { if ( $ skip_validation === false ) $ skip_validation = [ ] ; $ deserialised = self :: deserialise ( $ token ) ; $ claims = $ deserialised [ 'claims' ] ; if ( count ( $ deserialised [ 'signatures' ] ) > 1 ) { foreach ( $ deserialised [ 'signatures' ] as $ signature_obj ) { if ( isset ( $ signature_obj [ 'header' ] [ 'kid' ] ) ) { $ target_kid = $ signature_obj [ 'header' ] [ 'kid' ] ; if ( ( $ target_kid == $ kid ) || ( $ keys -> getById ( $ target_kid ) != null ) ) { $ headers = $ signature_obj [ 'headers' ] ; $ signing_input = $ signature_obj [ 'signing_input' ] ; $ signature = $ signature_obj [ 'signature' ] ; break ; } } throw new InvalidTokenException ( 'Cannot find verifiable signature' , InvalidTokenException :: TOKEN_PARSE_ERROR ) ; } } else { $ headers = $ deserialised [ 'signatures' ] [ 0 ] [ 'headers' ] ; $ signing_input = $ deserialised [ 'signatures' ] [ 0 ] [ 'signing_input' ] ; $ signature = $ deserialised [ 'signatures' ] [ 0 ] [ 'signature' ] ; } if ( isset ( $ headers [ 'crit' ] ) ) { foreach ( $ headers [ 'crit' ] as $ critical ) { if ( ! in_array ( $ critical , [ 'nbf' , 'exp' , 'alg' , 'kid' ] ) ) { throw new InvalidTokenException ( 'Critical header not supported: ' . $ critical , InvalidTokenException :: UNSUPPORTED_ERROR ) ; } } } if ( $ headers [ 'alg' ] != $ expected_alg ) throw new InvalidTokenException ( 'Unexpected algorithm' , InvalidTokenException :: SIGNATURE_VERIFICATION_ERROR ) ; $ signer = AlgorithmFactory :: create ( $ expected_alg ) ; try { if ( isset ( $ headers [ 'kid' ] ) ) $ kid = $ headers [ 'kid' ] ; $ result = $ signer -> verify ( $ signature , $ signing_input , $ keys , $ kid ) ; } catch ( KeyException $ e ) { throw new InvalidTokenException ( $ e -> getMessage ( ) , InvalidTokenException :: SIGNATURE_VERIFICATION_ERROR , $ e ) ; } catch ( CryptException $ e ) { throw new InvalidTokenException ( $ e -> getMessage ( ) , InvalidTokenException :: SIGNATURE_VERIFICATION_ERROR , $ e ) ; } if ( ! $ result ) throw new InvalidTokenException ( 'Incorrect signature' , InvalidTokenException :: SIGNATURE_VERIFICATION_ERROR ) ; $ time = time ( ) ; if ( isset ( $ claims [ 'nbf' ] ) && ! in_array ( 'nbf' , $ skip_validation ) ) { if ( $ time < $ claims [ 'nbf' ] - self :: $ TIME_ALLOWANCE ) throw new InvalidTokenException ( 'Too early due to nbf claim' , InvalidTokenException :: TOO_EARLY_ERROR , null , $ claims [ 'nbf' ] ) ; } if ( isset ( $ claims [ 'exp' ] ) && ! in_array ( 'exp' , $ skip_validation ) ) { if ( $ time > $ claims [ 'exp' ] + self :: $ TIME_ALLOWANCE ) throw new InvalidTokenException ( 'Too late due to exp claim' , InvalidTokenException :: TOO_LATE_ERROR , null , $ claims [ 'exp' ] ) ; } return new JWT ( $ headers , $ claims ) ; }
Decodes a serialised JWT.
Decodes a serialised JWT .
// Multiple signatures, choose one // Process crit // Check signatures // Check time, etc