Skip to content

#26 - Expose Refresh Token in Authenticated REST API requests #27

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions src/ManageTokens.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,20 @@ public static function init() {
'add_auth_headers_to_response'
] );

/**
* Add Auth Headers to REST REQUEST responses
*
* This allows clients to use WPGraphQL JWT Authentication
* tokens with WPGraphQL _and_ with REST API requests, and
* this exposes refresh tokens in the REST API response
* so folks can refresh their tokens after each REST API
* request.
*/
add_filter( 'rest_request_after_callbacks', [
'\WPGraphQL\JWT_Authentication\ManageTokens',
'add_auth_headers_to_rest_response'
], 10, 3 );

add_filter( 'graphql_access_control_allow_headers', [
'\WPGraphQL\JWT_Authentication\ManageTokens',
'add_jwt_allowed_headers'
Expand All @@ -72,6 +86,7 @@ public static function init() {
* @param array $fields The fields for the User type in the GraphQL Schema
*
* @return array $fields
* @throws \Exception
*/
public static function add_user_fields( $fields ) {

Expand Down Expand Up @@ -278,6 +293,14 @@ public static function use_custom_user_expiration( $expiration ) {
*/
public static function add_tokens_to_graphql_response_headers( $headers ) {

/**
* If the request _is_ SSL, or GRAPHQL_DEBUG is defined, return the tokens
* otherwise do not return them.
*/
if ( ! is_ssl() && ( ! defined( 'GRAPHQL_DEBUG' ) || true !== GRAPHQL_DEBUG ) ) {
return $headers;
}

/**
* If there's a Refresh-Authorization token in the request headers, validate it
*/
Expand Down Expand Up @@ -318,6 +341,56 @@ public static function add_tokens_to_graphql_response_headers( $headers ) {

}

/**
* Expose X-JWT-Refresh tokens in the response headers for REST requests.
*
* This allows clients the ability to Authenticate with WPGraphQL, use the token
* with REST API Requests, but get new refresh tokens from the REST API Headers
*
* @return \WP_HTTP_Response
* @throws \Exception
*/
public static function add_auth_headers_to_rest_response( \WP_HTTP_Response $response, $handler, $request ) {

/**
* If the request _is_ SSL, or GRAPHQL_DEBUG is defined, return the tokens
* otherwise do not return them.
*/
if ( ! is_ssl() && ( ! defined( 'GRAPHQL_DEBUG' ) || true !== GRAPHQL_DEBUG ) ) {
return $response;
}

/**
* Note: The Access-Control-Expose-Headers aren't directly filterable
* for REST API responses, so this overrides them altogether.
*
* This isn't ideal, as any other plugin could override as well.
*
* Might need a patch to core to allow for individual filtering.
*/
$response->set_headers( [
'Access-Control-Expose-Headers' => 'X-WP-Total, X-WP-TotalPages, X-JWT-Refresh',
] );

$refresh_token = null;

$validate_auth_header = Auth::validate_token( str_ireplace( 'Bearer ', '', Auth::get_auth_header() ), false );

if ( ! is_wp_error( $validate_auth_header ) && ! empty( $validate_auth_header->data->user->id ) ) {

$refresh_token = Auth::get_refresh_token( new \WP_User( $validate_auth_header->data->user->id ), false );

}

if ( $refresh_token ) {
$response->set_headers( [
'X-JWT-Refresh' => $refresh_token,
] );
}

return $response;
}

/**
* Expose the X-JWT-Refresh tokens in the response headers. This allows
* folks to grab new refresh tokens from authenticated requests for subsequent use.
Expand Down