Skip to content

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

@jherndon46

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions