Skip to content

Filter the token before returning it in Auth::validate_token #183

Description

@jherndon46

We would like to add custom validation logic to Auth::validate_token.

It would be nice if the token were filtered before being returned from that function, like so:

$token = apply_filters( 'graphql_jwt_auth_validate_token', $token );

Full function with this change:

`
public static function validate_token( $token = null, $refresh = false ) {

	self::$is_refresh_token = ( true === $refresh ) ? true : false;

	/**
	 * If a token isn't passed to the method, check the Authorization Headers to see if a token was
	 * passed in the headers
	 *
	 * @since 0.0.1
	 */
	if ( empty( $token ) ) {

		/**
		 * Get the Auth header
		 */
		$auth_header = self::get_auth_header();

		/**
		 * If there's no $auth, return an error
		 *
		 * @since 0.0.1
		 */
		if ( empty( $auth_header ) ) {
			return $token;
		} else {
			/**
			 * The HTTP_AUTHORIZATION is present verify the format
			 * if the format is wrong return the user.
			 */
			list( $token ) = sscanf( $auth_header, 'Bearer %s' );
		}

	}

	/**
	 * If there's no secret key, throw an error as there needs to be a secret key for Auth to work properly
	 */
	if ( ! self::get_secret_key() ) {
		// See https://github.com/wp-graphql/wp-graphql-jwt-authentication/issues/111
		self::set_status( 403 );
		return new \WP_Error( 'invalid-secret-key', __( 'JWT is not configured properly', 'wp-graphql-jwt-authentication' ) );
	}

	/**
	 * Decode the Token
	 */
	JWT::$leeway = 60;

	try {
		$token = ! empty( $token ) ? JWT::decode( $token, new Key( self::get_secret_key(), 'HS256') ) : null;
	} catch ( Exception $exception ) {
		$token = new \WP_Error( 'invalid-secret-key', $exception->getMessage() );
	}

	/**
	 * If there's no token listed, just bail now before validating an empty token.
	 * This will treat the request as a public request
	 */
	if ( empty( $token ) || is_wp_error( $token )  ) {
		return $token;
	}

	/**
	 * Allow multiple domains to be used as token iss value
	 * This is useful if you want to make your token valid over several domains
	 * Default value is the current site url
	 * Used along with the 'graphql_jwt_auth_token_before_sign' filter
	 */

	$allowed_domains = array(get_bloginfo('url'));
	$allowed_domains = apply_filters('graphql_jwt_auth_iss_allowed_domains', $allowed_domains);

	/**
	 * The Token is decoded now validate the iss
	 */

	if ( ! isset( $token->iss ) || ! in_array( $token->iss, $allowed_domains ) ) {
		// See https://github.com/wp-graphql/wp-graphql-jwt-authentication/issues/111
		self::set_status(401);
		return new \WP_Error( 'invalid-jwt', __( 'The iss do not match with this server', 'wp-graphql-jwt-authentication' ) );
	}

	/**
	 * So far so good, validate the user id in the token
	 */
	if ( ! isset( $token->data->user->id ) ) {
		// See https://github.com/wp-graphql/wp-graphql-jwt-authentication/issues/111
		self::set_status(401);
		return new \WP_Error( 'invalid-jwt', __( 'User ID not found in the token', 'wp-graphql-jwt-authentication' ) );
	}

	/**
	 * If there is a user_secret in the token (refresh tokens) make sure it matches what
	 */
	if ( isset( $token->data->user->user_secret ) ) {

		if ( Auth::is_jwt_secret_revoked( $token->data->user->id ) ) {
			// See https://github.com/wp-graphql/wp-graphql-jwt-authentication/issues/111
			self::set_status(401);
			return new \WP_Error( 'invalid-jwt', __( 'The User Secret does not match or has been revoked for this user', 'wp-graphql-jwt-authentication' ) );
		}
	}

	$token = apply_filters( 'graphql_jwt_auth_validate_token', $token );

	if ( is_wp_error( $token ) ) {
		self::set_status( 403 );
	}

	self::$is_refresh_token = false;

	return $token;

}`

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions