admin管理员组

文章数量:1403355

i want create a nextjs via headless woocommerce how can i add jwt auth to some methods and endpoints and allow others publicly for example i want restrict POST,DELETE,PUT methods for product and orders endpoint but allow GET method for them

i want create a nextjs via headless woocommerce how can i add jwt auth to some methods and endpoints and allow others publicly for example i want restrict POST,DELETE,PUT methods for product and orders endpoint but allow GET method for them

Share Improve this question asked Mar 21 at 10:22 sianamisianami 9791 gold badge5 silver badges12 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

I've used the plugin 'JWT Authentication for WP REST API' for the JWT authentication. And then created my own endpoints, and build the authentication check in it. I've tried this for WooCommerce endpoints, and this works the same way.

If you also want to use the same plugin for JWT authentication, please make sure to edit your .htaccess file and add the JWT token secret inside your wp-config.php, as explained in the plugin description: https://wordpress./plugins/jwt-authentication-for-wp-rest-api/

After doing that, we want to create an extra validation on specific WooCommerce REST routes, this can we do with the default WordPress rest_pre_dispatch filter like:

(In this example I check the route '/wc/v3/products' with the method 'POST', you can change this to the values you want):


function custom_rest_pre_dispatch($result, $wp_rest_server, $request) {
    // Check if the request is for the REST API
    if (!defined('REST_REQUEST') || !REST_REQUEST) {
        return $result;
    }

    // Check if $request is an instance of WP_REST_Request
    if (!($request instanceof WP_REST_Request)) {
        return $result;
    }

    // Get method
    $method = $request->get_method();

    // Get route
    $route = $request->get_route();

    // Check if the route contains for example '/wc/v3/products' and the method is POST
    if (
        $route == '/wc/v3/products' &&
        $method == 'POST'
    ) {
        // Check JWT header & get user ID
        $jwt_user_id = check_jwt_header_and_get_user_id($request);

        // Return the error if the JWT header is incorrect
        if (is_wp_error($jwt_user_id)) {
            return $jwt_user_id;
            die();
        }
    }

    return $result;
}
add_filter('rest_pre_dispatch', 'custom_rest_pre_dispatch', 10, 3);

What i've also done is created a custom function called check_jwt_header_and_get_user_id() that I use to check if the requested JWT header exists and to identify the user.

This function validates the JWT header and return the user ID of the user calling it:


// Function to check the JWT header and get the user ID
function check_jwt_header_and_get_user_id($request)
{
    // Check if Firebase\JWT\JWT and Firebase\JWT\Key are available
    if (!class_exists('Firebase\JWT\JWT') || !class_exists('Firebase\JWT\Key')) {
        return new WP_Error(
            'jwt_auth_bad_request',
            'JWT library not found.',
            [
                'status' => 403,
            ]
        );
    }

    // Get the auth_header from the request
    $auth_header = $request->get_header('Authorization');
    if (empty($auth_header)) {
        return new WP_Error('no-auth-header', __('No auth header', 'ricks-anytimers-app'), array('status' => 401));
    }

    // Extract the authorization header
    [$token] = sscanf($auth_header, 'Bearer %s');

    // If the format is not valid return an error
    if (!$token) {
        return new WP_Error(
            'jwt_auth_bad_auth_header',
            'Authorization header malformed.',
            [
                'status' => 403,
            ]
        );
    }

    // Get the JWT_AUTH_SECRET_KEY defined in the wp-config.php
    $secret_key = JWT_AUTH_SECRET_KEY;

    // Create an instance of the JWT class
    $jwt = new \Firebase\JWT\JWT();

    // Decode the token
    $token = $jwt->decode($token, new \Firebase\JWT\Key($secret_key, apply_filters('jwt_auth_algorithm', 'HS256')));

    // Check if token is not empty and is an object
    if (empty($token) || !is_object($token)) {
        return new WP_Error(
            'jwt_auth_bad_token',
            'Token is empty or not an object.',
            [
                'status' => 403,
            ]
        );
    }

    // The Token is decoded now validate the iss, return error if it does not match
    if (empty($token->iss) || $token->iss !== get_bloginfo('url')) {
        return new WP_Error(
            'jwt_auth_bad_iss',
            'The iss do not match with this server',
            [
                'status' => 403,
            ]
        );
    }

    // So far so good, validate the user id in the token
    if (!isset($token->data->user->id) || empty($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',
            [
                'status' => 403,
            ]
        );
    }

    // Return the user id
    return (int)$token->data->user->id;
}

本文标签: how customize usage of jwt authentication for woocommerce and wordpress apiStack Overflow