2

I am working on generating a JWT token for the users who log in to my site using a plugin JWT Auth and that token will be used for a external dashboard.

The issue that I am facing is that for generating a JWT token you need to pass username and password as form-data to /wp-json/jwt-auth/v1/token endpoint but the password that is stored in the database is hashed and cannot be decrypted so what is the solution for this? I cannot send plain text password to the endpoint.

Looking forward to your suggestions.

7
  • 1
    I believe the idea is that you're supposed to send it from the user's input, not from the database directly. If you're trying to authenticate an app as a particular user without user input then JWT probably isn't what you want. Feb 26, 2021 at 13:33
  • @JacobPeattie ... getting the password of the user directly from the input isn't a good idea and it exposes the users passwords. I have to use the JWT token because the other dashboard requires it. Feb 26, 2021 at 13:49
  • 3
    How do you think login forms work? Feb 26, 2021 at 14:16
  • 1
    As long as you POST to a https connection (and password is part of post body), the password should not leak from the request.
    – kero
    Feb 26, 2021 at 14:59
  • Are you trying to generate a JWT token for a current logged-in user session on your site? You can probably just instantiate the JWTAuth\Auth class and call generate_token with the current user object. Or add a new endpoint, or modify the existing endpoint, to use the current logged-in user from session cookies and not require username and password if the user is logged in.
    – Rup
    Feb 26, 2021 at 15:17

2 Answers 2

1

For the developers who are facing the similar issue here is what I have done to achieve the desired results.

The best way would be to develop the functionality from scratch but due to a tight deadline I opted to modify the JWT Auth Plugin

I have modified the method get_token in the file class-auth.php. What I have done is that at first the method was looking for params username and password and I have modified it to receive userID as the param required. Why userID ? It is because I am running a cURL call to get the user data after the user sign in. Here is the code for the get_token method if anyone wants to use it. Although it was a small modification but it produces the required results. Thank you all for the suggestions. Happy Coding

public function get_token(WP_REST_Request $request)
    {
        $secret_key = defined('JWT_AUTH_SECRET_KEY') ? JWT_AUTH_SECRET_KEY : false;

        $userID = $request->get_param('user_id');
        $custom_auth = $request->get_param('custom_auth');

        // First thing, check the secret key if not exist return a error.
        if (!$secret_key) {
            return new WP_REST_Response(
                array(
                    'success' => false,
                    'statusCode' => 403,
                    'code' => 'jwt_auth_bad_config',
                    'message' => __('JWT is not configurated properly.', 'jwt-auth'),
                    'data' => array(),
                )
            );
        }

        // Getting data for the logged in user.
        $user = get_user_by('id', $userID);

        // If the authentication is failed return error response.
        if (!$user) {
            // $error_code = $user->get_error_code();

            return new WP_REST_Response(
                array(
                    'success' => false,
                    'statusCode' => 403,
                    'code' => 404,
                    'message' => 'User does not exists.',
                    'data' => array(),
                )
            );
        }

        return $this->generate_token($user, false);
    }
0

You could use custom_auth parameter to handle this kind of situations


Edited

The JWT has a filter called jwt_auth_custom_auth, it will run when it receives a payload that contain 'custom_auth' you need to hook to that filter using add_fitler function see the code below.

In my case the first block of code goes to my rest api custom endpoint where i used it to login/register users using only email address

The second block is to hook to the filter and i chose to put it in my plugin file, but you can put it also in you theme's function.php file

You can see the logic in this file wp-content\plugins\jwt-auth\class-auth.php lines 115 -> 160



$_request = new WP_REST_Request( 'POST', '/jwt-auth/v1/token' );
$_request->set_header( 'content-type', 'application/json' );
$_request->set_body(
    json_encode(
        [
            'username'    => $email,
            'custom_auth' => true,
        ]
    )
);
$response = rest_do_request( $_request );
return $response->data['data']['token']; // this will return a token

And in your function.php

add_filter(
    'jwt_auth_do_custom_auth',
    function ( $custom_auth_error, $username, $password, $custom_auth ) {
        if ( is_wp_error( $custom_auth_error ) ) {
            return null;
        }
        $user = get_user_by( 'email', $username );
        return $user;
    },10,4);

I hope this helps

NOTE: not tested

2
  • Can you elaborate on your code to make things a little more clear - where does the first block go? It looks like it should be in a function (the return statement), does that function hook in somewhere?
    – phatskat
    Jun 8, 2021 at 15:47
  • I have updated my answer, I hope it helps
    – Suhail
    Jun 9, 2021 at 12:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.