Access Token is not valid or has expired
-
HI!
I has been working with the plugin JWT and it works good, but the Token is not longer more than 1 week, then and received “Access Token is not valid or has expired” in the response.I need to create a new Token and change it in my code, how I can solve this problem? any idea?
Thanks!!
Alvar Arias
-
By default AccessToken expiration is set to 7 days. When you get the expired token error, you should logout the user on the client-side (remove the local data about the logged in user) and redirect them to the login page.
If you want to change the expiration of the AccessToken, you can do it by adding a filter like this:
add_filter( 'jwt_auth_expire', function( $expire, $issued_at ) { return $issued_at + ( DAY_IN_SECONDS * 7 ); // Change the number 7 to the number of days you want the token to last }, 10, 2 );
To solve this problem I allowed myself to add a route and share if you want to integrate it in a next release
Router
jwt-authentication-for-wp-rest-api/public/class-jwt-auth-public.phpregister_rest_route($this->namespace, 'token/refresh', array( 'methods' => 'POST', 'callback' => array($this, 'jwt_auth_refresh_token'), ));
function jwt_auth_refresh_token
public function jwt_auth_refresh_token($request) { $auth = isset($_SERVER['HTTP_AUTHORIZATION']) ? $_SERVER['HTTP_AUTHORIZATION'] : false; /* Double check for different auth header string (server dependent) */ if (!$auth) { $auth = isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION']) ? $_SERVER['REDIRECT_HTTP_AUTHORIZATION'] : false; } if (!$auth) { return new WP_Error( 'jwt_auth_no_auth_header', 'Authorization header not found.', array( 'status' => 403, ) ); } $token = $request->get_param('token'); $email = $request->get_param('email'); $force = (is_null($request->get_param('force')))?false:$request->get_param('force'); /** Get the Secret Key */ $secret_key = defined('JWT_AUTH_SECRET_KEY') ? JWT_AUTH_SECRET_KEY : false; if (!$secret_key) { return new WP_Error( 'jwt_auth_bad_config', __('JWT is not configurated properly, please contact the admin', 'wp-api-jwt-auth'), array( 'status' => 403, ) ); } /** Try to decode the token */ //try { try { $token = JWT::decode($token, $secret_key, array('HS256'),$force); /** The Token is decoded now validate the iss */ if ($token->iss != get_bloginfo('url')) { /** The iss do not match, return error */ return new WP_Error( 'jwt_auth_bad_iss', __('The iss do not match with this server', 'wp-api-jwt-auth'), array( 'status' => 403, ) ); } /** So far so good, validate the user id in the token */ if (!isset($token->data->user->id)) { /** No user id in the token, abort!! */ return new WP_Error( 'jwt_auth_bad_request', __('User ID not found in the token', 'wp-api-jwt-auth'), array( 'status' => 403, ) ); } } catch (Exception $e) { $className = get_class($e); if ($className == "InvalidArgumentException") { $user = get_user_by('email', $email); if (!$user) { return new WP_Error( 'jwt_auth_invalid_email', 'Email not found', array( 'status' => 403, ) ); } $issuedAt = time(); $notBefore = apply_filters('jwt_auth_not_before', $issuedAt, $issuedAt); $expire = apply_filters('jwt_auth_expire', $issuedAt + (DAY_IN_SECONDS * 7), $issuedAt); $token = array( 'iss' => get_bloginfo('url'), 'iat' => $issuedAt, 'nbf' => $notBefore, 'exp' => $expire, 'data' => array( 'user' => array( 'id' => $user->data->ID, ), ), ); /** Let the user modify the token data before the sign. */ $token = JWT::encode(apply_filters('jwt_auth_token_before_sign', $token, $user), $secret_key); /** The token is signed, now create the object with no sensible user data to the client*/ $data = array( 'token' => $token, 'user_email' => $user->data->user_email, 'user_nicename' => $user->data->user_nicename, 'user_display_name' => $user->data->display_name, 'iss' => get_bloginfo('url'), 'iat' => $issuedAt, 'nbf' => $notBefore, 'exp' => $expire, ); if ($force) { throw new InvalidArgumentException('token is forced'); }<code></code> /** Let the user modify the data before send it back */ return apply_filters('jwt_auth_token_before_dispatch', $data, $user); } } return $auth; }
/wp-content/plugins/jwt-authentication-for-wp-rest-api/includes/vendor/firebase/php-jwt/src/jwt.php
in function function decode if ($force) { throw new InvalidArgumentException('token is forced'); }
Like this we can refresh token when expired
Hi @alvar05 @djboris88 , I’m going to work on refresh token this week. I expect to publish minor update to the plugin this week.
Btw, thanks for posting your solution @angelzeke , it can be reference for me.
Best,
BagusHi @contactjavas,
Thank you for this. I am just wondering what is your opinion on the need for refresh tokens. I understand that using two tokens, one that is short-lived for authorizing requests, and the other which is long-lived, which serves for requesting new authTokens, in theory provides at least a bit more security.
In practice, it all depends how securely does the client store the tokens. If it is in the local storage, or non-secure and non-httpOnly cookie (which is often not possible due to technical limitations), it really makes no difference. Because if malicious script can access the authToken, it can access the refreshToken as well, right? And if the refreshToken gets leaked, it is even worse than if it is not used at all. authToken would eventually expire, but refreshToken usually lasts for much longer, and can be used for generating unlimited number of authTokens.
I know it is really hard question, but it’s something that has been bothering me for the last few months. What is your opinion on this?
Hi @contactjavas ,
Any update on refresh token i am also having this issue what n how to deal with when the token is expired we can force user to login again instead we need to provide a new token when the token is expired.
- The topic ‘Access Token is not valid or has expired’ is closed to new replies.