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
553 stars 159 forks source link

get token using the 'WordPress REST API with JWT Authentication' plugin #152

Closed gordielachance closed 5 years ago

gordielachance commented 5 years ago

I'm trying to build a Wordpress plugin that is an API which can be queried from remote websites.

I want to secure it with JWT web tokens, so I did install the JWT Authentication for WP REST API plugin. I read this article to configure it, and have a working setup (checked in Postman).

So I have my API website with JWT working.

Now, I want to request that API from the client website.

I need a token from the API website to be able to request it from outside. So, first, I need to generate that token when my user register and logs in on the API website.

I started to write some code but I'm stuck. Once the user is logged in, how can I make a post request to get the token ?

Also, is this the right way to process ? Generate a token on the API website and use it on the client website ? How/when will the token expire ?

Thanks!


add_action( 'init', array($this,'generate_user_token') );

public function generate_user_token(){
    $token = $this->get_token();
    if( is_wp_error($token) ) return $token;

    //store and show token so user can user it on client side.
}

private function get_token(){

    if ( !$user_id = get_current_user_id() ){
        return new WP_Error('user_not_logged','Cannot get token, user is not logged');
    }

    $args = array(
        'body' => array( 
            'username' => //how could I fill this parameters required by JWT-AUTH ?
            'password' => //how could I fill this parameters required by JWT-AUTH ?
        ),
    );

    $request = wp_remote_post( get_rest_url(null,'jwt-auth/v1/token'), $args );
    if (is_wp_error($request)) return $request;

    $response = wp_remote_retrieve_body( $request );
    if (is_wp_error($response)) return $response;

    $response = json_decode($response, true);

    //check for errors
    $code = ( isset($response['code']) ) ? $response['code'] : null;
    $message = ( isset($response['message']) ) ? $response['message'] : null;
    $data = ( isset($response['data']) ) ? $response['data'] : null;
    $status = ( isset($data['status']) ) ? $data['status'] : null;

    if ( $code && ($status >= 400) ){
        return new WP_Error($code,$message,$data );
    }

    return $response['token'];

}

}
Mulli commented 5 years ago

The plugin suggest that you use their end point /jwt-auth/v1/token All you need is to provide user name & password and you will get a token in return

gordielachance commented 5 years ago

yeah, but in Wordpress, I can't get the user's password ! What I would like is that, when the user logs in, a token would be stored in the user's metas. Possible ?

Thanks

Le jeu. 28 mars 2019 à 15:43, Mulli Bahr notifications@github.com a écrit :

The plugin suggest that you use their end point /jwt-auth/v1/token All you need is to provide user name & password and you will get a token in return

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/Tmeister/wp-api-jwt-auth/issues/152#issuecomment-477555106, or mute the thread https://github.com/notifications/unsubscribe-auth/AD42za2wko2VZ88PHCauFeEwqcU-RhKOks5vbKZfgaJpZM4cE1ox .

Mulli commented 5 years ago

I just realized that your plugin is in the middle between client requests and WP core and actually running on the site server (and not on the client side).

So either your client is a registered user and can provide its password Or your plugin has its own user & password in your WordPress site. I cannot see other ways to have a password.

gordielachance commented 5 years ago

Yes, sorry, I didn't explain. My idea is to use the plugin to generate user API keys.
So, the user subscribes on the API website and gets a token.
Then I can give him some capabilities to use the API. I would thus need to store the token somewhere so I can display it on its profile...

Mulli commented 5 years ago

I am using it and its perfect. I made some changes:

  1. In few places I test for error - the code assume success and its not always the case. Just Imagine the zillion configuration out there - so error log message suffice.
  2. My client is using json format - the code does not support it. I added simple code the extracts the username & password.

All seems OK now.

gordielachance commented 5 years ago

I don't get it - does this help to solve my problem ? Thanks.

Mulli commented 5 years ago

I am not sure that we see things the same way. Once user logs in with user name & password, the plugin provides a token. Wordpress user once logged in, has capabilities that you can use in your app. As I understand it - you do not need to display the token in the profile, nor it can be used in this way

gordielachance commented 5 years ago

Wordpress user once logged in, has capabilities that you can use in your app.

I understand that (and it works fine !)

Once user logs in with user name & password, the plugin provides a token.

Ok, currently I manage to get that token using Postman - but that's hard to understand for newbies (my users); I want to offer something easy to use (without the need of installing/learning new stuff).

What I would need is that the user logs in on my API website (wordpress), using the regular WP url (eg. ../wordpress/wp-login.php).

Do you see the idea ? Thanks for your help !

Mulli commented 5 years ago

I am not the plugin owner/author, just a user trying to help. I feel that displaying a token is not a safe way to go.

Then the user can copy/paste that token and use it to connect to my API, on their website.

Please elaborate the need behind: "connect to my API, on their website" What is the application? Why you want clients website logging to your site? Why not providing plugin? etc...

Please note that if you allow it, logging to your site is easy & simple. I cannot see the good reason why it gets complicated. Sorry, for the lengthy ping pong we have here :-(

gordielachance commented 5 years ago

No problems, thanks for your help !

Why you want clients website logging to your site? Why not providing plugin? etc...

I do precisly provide a plugin, but it uses an external API that the plugin calls.
That API runs under WP with the JWT AUTH plugin, because users needs a "membership" to get access to the API. So, if I give them specific capabilities AND a token, they will be able to use that API through the plugin. You get it ?

Thanks !

Mulli commented 5 years ago

Just came across this page Hope it helps

gordielachance commented 5 years ago

Hi Mully, unhopefully it's seems that it is only for internal requests, not for remote requests :

Use _rest_dorequest to make API requests internally within other WordPress code

gordielachance commented 5 years ago

@Tmeister Hi ! Could you help ? Thanks !

Mulli commented 5 years ago

I can try. Look please at this link and the concept of "token delegation".

gordielachance commented 5 years ago

Ok, seen it; but that's quite too theorical for me (coding is a hobby, i'm not a professional).
What should I do ? So you are the depo owner but not the plugin's creator ? Thanks!

gordielachance commented 5 years ago

Or maybe I should do this differently, but could you tell me if it's a good idea ?

-- client --

--api--

Should I work like this ? Thanks for your help, again !

Mulli commented 5 years ago

Its not clear to me to which web server clients are connecting. Where is your plugin? Where is the "api" ? Please be super accurate. Thanks.

gordielachance commented 5 years ago

So,

So, the client and the API plugins do not share the same server / Wordpress installation.

JWT Authentication for the WP REST API is installed on the API side and I want to use it to allow users of the client plugin to request the API.

So my idea was that when a client wants access to the API, he has to create an account on the API website. It would generate a token; and he would use it on the client side, in the client plugin settings, to enable access to the API.

Is that clear enough ? Sorry I speak french and maybe what I say is a little confused...

Thanks again.

Mulli commented 5 years ago

Your English is fine. I needed your explanation for double check... You are describing a very common scenario where one calls a server (your "api" that provides data...) and the server provides service only for registered users. The service is called from your public plugin (from client website/server). I hope I get it correct now.

I describe below the scenario with or without jwt (its not necessarily needed...) depending on the flow you prefer.

So,

  1. Your client (Myself for example...) downloads the public plugin from WP.org & Install & Activate
  2. The user (e.h. myself) login to your server to generate an account With JWT: YOUR server generates an account for me with appropriate credentials. AND display a page with generated token (JWT) to copy&paste to public plugin settings. W/O JWT: you can generate your own token: YOUR-HASH-FUNCTION(username, password) AND display a page with generated your token for copy&paste to public plugin settings.
  3. Now - Client can use your public plugin to access the API Each request to your API will check that the user is allowed to perform the request.

Good luck

gordielachance commented 5 years ago

That's it !

With JWT: YOUR server generates an account for me with appropriate credentials. AND display a page with generated token (JWT) to copy&paste to public plugin settings.

Exactly what I need. And this is my original question : how can I display the token on the user profile (API-side) ? And eventually, how can I choose (or eventually revoke) the validity of the token ?

Thanks a lot Mulli.

Mulli commented 5 years ago

how can I display the token on the user profile (API-side) ?

see this link,

validity of the token ?

Look for expiery time at the JWT dcumentation

gordielachance commented 5 years ago

Hi Mulli, me again, still struggling with this (but had no time recently to work on it, that's why I'm replying so late). My goal is to filter users profiles so that

So regarding your answers in the previous post, my question was more like

1/ What is the function to get the user token (so I can display it on the profile) ? 2/ I've seen that there is a filter to change the expiry time. But is it possible to revoke the access (delete the token) or change its expiracy date ?

Thanks!

gordielachance commented 5 years ago

Here's an attempt to be more clear : https://github.com/Tmeister/wp-api-jwt-auth/issues/160 :)