Tmeister / wp-api-jwt-auth

A simple plugin to add JSON Web Token (JWT) Authentication to WP REST API
GNU General Public License v2.0
549 stars 159 forks source link

How do I reuse the existing session/authentication from a logged in WP user? #234

Closed OEvans117 closed 1 year ago

OEvans117 commented 2 years ago

So my current goal is to reuse an existing Wordpress user's (that has been authenticated) session and be able to access the endpoints that one of my WP plugin (dokan) offers that requires a JWT or Basic Auth header. I want to avoid the process of the user (from my plugin) having to login on both wordpress, and again to retrieve JWT token. I chose JWT and this plugin because I figured it could possibly help me acheive this goal.

I thought the solution could possibly involve (in my PHP code) using wp_get_current_user() and retrieveing user and password from there to programmatically generate the JWT token and calling /wp-json/jwt-auth/v1/token, however it seems getcurrentuser method returns the hashed password, so I'm not sure if it would return a correct JWT token.

Another solution I thought of was checking cookies/local storage for any JWT tokens the plugin stores after logging in on Wordpress, so I could just reuse them in my code... However, this doesn't seem to happen when I login. Is it possible to hook onto the login function and force the creation of a JWT token that's stored into cookies, or would this be unsafe/unviable?

I cannot think of any other solution really, so I am at a bit of a standstill with this whole situation. Does anyone out there know what I can do?

pesseba commented 2 years ago

You can use a internal rest api request in Wordpress to get a token with logged user. Just add a filter in wp authentication to skip the username and password verification. The plugin use this wordpress method internaly to generate a token: For example (I didn't test this):

add_filter('wp_authenticate_user',function($u, $p){ return wp_get_current_user(); },10,2);
$request = new WP_REST_Request( 'POST', '/jwt-auth/v1/token');
$response = rest_do_request( $request );

So, the response give you the token

OEvans117 commented 2 years ago

You can use a internal rest api request in Wordpress to get a token with logged user. Just add a filter in wp authentication to skip the username and password verification. The plugin use this wordpress method internaly to generate a token: For example (I didn't test this):

add_filter('wp_authenticate_user',function($u, $p){ return wp_get_current_user(); },10,2);
$request = new WP_REST_Request( 'POST', '/jwt-auth/v1/token');
$response = rest_do_request( $request );

So, the response give you the token

So, as I understand, the method wp_authenticate_user is used by the plugin to retrive the JWT token. However, you are now changing it to return wp_get_current_user regardless of whether username and password was passed in. I'm not familiar with this wp_authenticate_user method, but I am interesting in knowing whether this change has any security implications on other parts of the website/would break other plugins / parts of the website?

Thanks for the reply :)

EDIT:

I have tried it and am getting the following issue:

Fatal error: Uncaught Error: Object of class WP_User could not be converted to string in /home/test/domains/test.com/public_html/wp-includes/formatting.php:5373 Stack trace: #0 /home/test/domains/test.com/public_html/wp-includes/formatting.php(5373): preg_replace() #1 /home/test/domains/test.com/public_html/wp-includes/formatting.php(2104): wp_strip_all_tags() #2 /home/test/domains/test.com/public_html/wp-includes/pluggable.php(591): sanitize_user() #3 /home/test/domains/test.com/public_html/wp-content/plugins/jwt-authentication-for-wp-rest-api/public/class-jwt-auth-public.php(122): wp_authenticate() #4 /home/test/domains/test.com/public_html/wp-includes/rest-api/class-wp-rest-server.php(1141): Jwt_Auth_Public->generate_token() #5 /home/test/domains/test.com/public_html/wp-includes/rest-api/class-wp-rest-server.php(988): WP_REST_Server->respond_to_request() #6 /home/test/domains/test.com/public_html/wp-includes/ in /home/test/domains/test.com/public_html/wp-includes/formatting.php on line 5373

Am I supposed to add all the code in the functions.php file or just the add_filter?

OEvans117 commented 2 years ago

Update - I have managed to complete my desired goal using this answer: https://wordpress.stackexchange.com/a/384179 and it works perfectly.

The only thing I'm wondering now, is if someone can pitch in and tell me if this has any security disadvantages to it?

Tmeister commented 1 year ago

Due to this fix is not part of the plugin, I'm closing the issue.