Skip to content

Commit ce2341c

Browse files
authored
Merge pull request #27 from wp-graphql/feature/#26-expose-jwt-refresh-in-rest-response-headers
#26 - Expose Refresh Token in Authenticated REST API requests
2 parents f40bd67 + adb4f8f commit ce2341c

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

src/ManageTokens.php

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,20 @@ public static function init() {
5959
'add_auth_headers_to_response'
6060
] );
6161

62+
/**
63+
* Add Auth Headers to REST REQUEST responses
64+
*
65+
* This allows clients to use WPGraphQL JWT Authentication
66+
* tokens with WPGraphQL _and_ with REST API requests, and
67+
* this exposes refresh tokens in the REST API response
68+
* so folks can refresh their tokens after each REST API
69+
* request.
70+
*/
71+
add_filter( 'rest_request_after_callbacks', [
72+
'\WPGraphQL\JWT_Authentication\ManageTokens',
73+
'add_auth_headers_to_rest_response'
74+
], 10, 3 );
75+
6276
add_filter( 'graphql_access_control_allow_headers', [
6377
'\WPGraphQL\JWT_Authentication\ManageTokens',
6478
'add_jwt_allowed_headers'
@@ -72,6 +86,7 @@ public static function init() {
7286
* @param array $fields The fields for the User type in the GraphQL Schema
7387
*
7488
* @return array $fields
89+
* @throws \Exception
7590
*/
7691
public static function add_user_fields( $fields ) {
7792

@@ -278,6 +293,14 @@ public static function use_custom_user_expiration( $expiration ) {
278293
*/
279294
public static function add_tokens_to_graphql_response_headers( $headers ) {
280295

296+
/**
297+
* If the request _is_ SSL, or GRAPHQL_DEBUG is defined, return the tokens
298+
* otherwise do not return them.
299+
*/
300+
if ( ! is_ssl() && ( ! defined( 'GRAPHQL_DEBUG' ) || true !== GRAPHQL_DEBUG ) ) {
301+
return $headers;
302+
}
303+
281304
/**
282305
* If there's a Refresh-Authorization token in the request headers, validate it
283306
*/
@@ -318,6 +341,56 @@ public static function add_tokens_to_graphql_response_headers( $headers ) {
318341

319342
}
320343

344+
/**
345+
* Expose X-JWT-Refresh tokens in the response headers for REST requests.
346+
*
347+
* This allows clients the ability to Authenticate with WPGraphQL, use the token
348+
* with REST API Requests, but get new refresh tokens from the REST API Headers
349+
*
350+
* @return \WP_HTTP_Response
351+
* @throws \Exception
352+
*/
353+
public static function add_auth_headers_to_rest_response( \WP_HTTP_Response $response, $handler, $request ) {
354+
355+
/**
356+
* If the request _is_ SSL, or GRAPHQL_DEBUG is defined, return the tokens
357+
* otherwise do not return them.
358+
*/
359+
if ( ! is_ssl() && ( ! defined( 'GRAPHQL_DEBUG' ) || true !== GRAPHQL_DEBUG ) ) {
360+
return $response;
361+
}
362+
363+
/**
364+
* Note: The Access-Control-Expose-Headers aren't directly filterable
365+
* for REST API responses, so this overrides them altogether.
366+
*
367+
* This isn't ideal, as any other plugin could override as well.
368+
*
369+
* Might need a patch to core to allow for individual filtering.
370+
*/
371+
$response->set_headers( [
372+
'Access-Control-Expose-Headers' => 'X-WP-Total, X-WP-TotalPages, X-JWT-Refresh',
373+
] );
374+
375+
$refresh_token = null;
376+
377+
$validate_auth_header = Auth::validate_token( str_ireplace( 'Bearer ', '', Auth::get_auth_header() ), false );
378+
379+
if ( ! is_wp_error( $validate_auth_header ) && ! empty( $validate_auth_header->data->user->id ) ) {
380+
381+
$refresh_token = Auth::get_refresh_token( new \WP_User( $validate_auth_header->data->user->id ), false );
382+
383+
}
384+
385+
if ( $refresh_token ) {
386+
$response->set_headers( [
387+
'X-JWT-Refresh' => $refresh_token,
388+
] );
389+
}
390+
391+
return $response;
392+
}
393+
321394
/**
322395
* Expose the X-JWT-Refresh tokens in the response headers. This allows
323396
* folks to grab new refresh tokens from authenticated requests for subsequent use.

0 commit comments

Comments
 (0)