Skip to content

Commit

Permalink
Merge pull request #20 from alleyinteractive/feature/jwt-payload
Browse files Browse the repository at this point in the history
Allow additional claims to be added to the JWT
  • Loading branch information
srtfisher authored Feb 26, 2024
2 parents bb7d522 + b2a2be8 commit c8436b3
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 4 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

All notable changes to `wp-rest-guard` will be documented in this file.

## v1.2.1 - 2024-02-26

- Allow the claims to be added to added to a generated JWT via filter.

## v1.2.0 - 2024-02-22

- Add support for authenticated users interacting with the REST API.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# REST API Guard

Stable tag: 1.2.0
Stable tag: 1.2.1

Requires at least: 6.0

Expand Down
17 changes: 15 additions & 2 deletions plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,6 @@ function get_jwt_secret(): string {
/**
* Generate a JSON Web Token (JWT).
*
* The JWT payload is intentionally not filtered to prevent
*
* @param int|null $expiration The expiration time of the JWT in seconds or null for no expiration.
* @param WP_User|int|null $user The user to include in the JWT or null for no user.
* @return string
Expand All @@ -349,6 +347,21 @@ function generate_jwt( ?int $expiration = null, WP_User|int|null $user = null ):

$payload['sub'] = $user->ID;
$payload['user_login'] = $user->user_login;

/**
* Filter the additional claims to include in the JWT.
*
* The filer cannot modify any existing claims, only add new ones.
*
* @param array<string, mixed> $additional_claims The additional claims to include in the JWT.
* @param WP_User|null $user The user to include in the JWT.
* @param array<string, mixed> $payload The payload of the JWT.
*/
$additional_claims = apply_filters( 'rest_api_guard_jwt_additional_claims', [], $user, $payload );

if ( is_array( $additional_claims ) ) {
$payload = array_merge( $additional_claims, $payload );
}
}

return JWT::encode( $payload, get_jwt_secret(), 'HS256' );
Expand Down
2 changes: 1 addition & 1 deletion readme.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
=== REST API Guard ===
Stable tag: 1.2.0
Stable tag: 1.2.1
Requires at least: 6.0
Tested up to: 6.3
Requires PHP: 8.0
Expand Down
33 changes: 33 additions & 0 deletions tests/RestApiGuardTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
namespace Alley\WP\REST_API_Guard\Tests;

use Firebase\JWT\JWT;
use Firebase\JWT\Key;

use function Alley\WP\REST_API_Guard\generate_jwt;
use function Alley\WP\REST_API_Guard\get_jwt_secret;

use const Alley\WP\REST_API_Guard\SETTINGS_KEY;

Expand Down Expand Up @@ -281,4 +283,35 @@ public static function jwtDataProviderAuthenticated(): array {
'empty' => [ 'invalid', '' ],
];
}

public function test_additional_jwt_claims() {
add_filter(
'rest_api_guard_jwt_additional_claims',
function ( $claims, $user ) {
$claims['user_email'] = $user->user_email;
$claims['sub'] = 1234;

return $claims;
},
10,
2,
);

add_filter( 'rest_api_guard_user_authentication_jwt', fn () => true );

$user = static::factory()->user->create_and_get();

$token = generate_jwt( user: $user );

$this
->with_header( 'Authorization', "Bearer {$token}" )
->get( '/wp-json/wp/v2/users/me' )
->assertOk();

// Ensure the additional claim is present.
$decoded = JWT::decode( $token, new Key( get_jwt_secret(), 'HS256' ) );

$this->assertEquals( $user->user_email, $decoded->user_email );
$this->assertEquals( $user->ID, $decoded->sub ); // Ensure it cannot overwrite a claim.
}
}

0 comments on commit c8436b3

Please sign in to comment.