wp-graphql / wp-graphql-jwt-authentication

Authentication for WPGraphQL using JWT (JSON Web Tokens)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Data security question

catedm opened this issue · comments

Hey everyone,

I have a question about data security when using the plugin. Here is the problem I am facing:

  • Our platform is a subscription based service that serves up paid content from WP graphql to a decoupled frontend application. WP is the CMS that houses our content via custom post types, and the frontend fetches the content from WP via WPGraphQL.
  • Users are allowed to browse a limited version of the content before making a paid subscription.
  • The problem is that - in the network response, our WPGraphQL calls return all of the content, including the premium paid content. So if someone wanted to steal our premium content, they could open up the developer tools, dig into the network calls to our WP site and get it from the data object that gets returned in the response.

Is there a way to hide the data object in the response using the plugin?

commented

You could create a custom resolver like this for the fields that you would like to protect:

add_filter('graphql_my_post_type_fields', function ($fields) {
    $fields['content'] = [
        'type' => 'String',
        'resolve' => function ($post) {
            $user = wp_get_current_user();
            $is_premium = get_post_meta($post->ID, 'is_premium', true);

            // Check for the X-My-Backend-API-Key header
            $header_api_key = $_SERVER['HTTP_X_MY_BACKEND_API_KEY'] ?? '';
            $is_authorized_backend = $header_api_key === MY_AUTHORIZED_BACKEND_API_KEY;

            if ($is_premium && !$is_authorized_backend && !in_array('paid_subscriber', $user->roles)) {
                // If the content is premium and the request is not from an authorized backend or the user is not a paid subscriber, return limited content or an error
                return "You need a paid subscription to view this content.";
            } else {
                // If the content is not premium, the request is from an authorized backend, or the user is a paid subscriber, return the content
                return $post->post_content;
            }
        },
    ];

    return $fields;
}, 10, 1);
commented

fetch(YOUR_GRAPHQL_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-My-Backend-API-Key': 'your_secure_api_key_here', }, body: JSON.stringify({ query: YOUR_GRAPHQL_QUERY }), });

This way NextJS can fetch all the content when building its bundle, and the user can directly fetch from the WPGraphQL server should you choose to allow so.
To make it nicer feel free to wrap it into a class, and use your own methods to check whether the user should have access to the post. Let me know if you have any questions.