usefulteam / jwt-auth

WordPress JSON Web Token Authentication
https://wordpress.org/plugins/jwt-auth/
122 stars 48 forks source link

Invalidate token. #29

Closed omarkhatibco closed 3 years ago

omarkhatibco commented 3 years ago

Hi,

is there any endpoint or a function that I can call and invalidate the token ? let's say the logout function for Example.

pesseba commented 3 years ago

Tokens are revoked on password change. You can call this action to simulate the process:

do_action('after_password_reset', {the_user_id_you_are_changing}, '');

omarkhatibco commented 3 years ago

Hi @pesseba ,

thanks for your help, but it did not work, also it trigger the password changed email.

omarkhatibco commented 3 years ago

Hi @pesseba,

it seems that there is no way to invalidate a jwt token.

so I just blacklisted the token in cache. then check it before serving the request.

I hope this got implemented by you, I'm happy to open a pull request if you want !

Logout function which just save the token in the cache

  public function handleLogout(WP_REST_Request $request)
  {
    $cache = new FilesystemCache(DOCTRINE_CACHE);

    $authHeader = $request->get_header('authorization');

    list($token) = sscanf($authHeader, 'Bearer %s');

    $cache->save($token, true);

    $result = [
      'message' => 'ok',
    ];

    return rest_ensure_response($result);
  }
}

then a Wordpress rest_pre_dispatch filter to check if the token is blacklisted.

add_filter('rest_pre_dispatch', function ($result, $server, $request) {
  $cache = new FilesystemCache(DOCTRINE_CACHE);
  $authHeader = $request->get_header('authorization');
  list($token) = sscanf($authHeader, 'Bearer %s');
  if ($token) {

    $isTokenBlacklisted = $cache->fetch($token);

    if ($isTokenBlacklisted) {
      return new WP_REST_Response(
        array(
          'success'    => false,
          'statusCode' => 403,
          'code'       => 'jwt_auth_user_not_found',
          'message'    => __("User doesn't exist", 'jwt-auth'),
          'data'       => array(),
        ),
        403
      );
    }
  }

  return $result;
}, 9, 3);
pesseba commented 3 years ago

@omarkhatibco blacklist tokens with cache is not a good way. Store tokens is not recommended and Rest API calls runs out browsers too, like mobile aplications. So the feature you need already exists in code, but it is private.

Try the other action to avoid email trigger, like this:

do_action('profile_update', {the_user_id_you_are_changing}, (object)array('user_pass'=>'') );

I tested here and it worked!

omarkhatibco commented 3 years ago

Hi @pesseba,

it did not work either. I use the Wordpress.org version, which last update was from 8 Months, maybe I should use github version ?

pesseba commented 3 years ago

@omarkhatibco that's it. You should use the github version! @contactjavas I don't know how to update wp version.