wp-graphql / wp-graphql-jwt-authentication

Authentication for WPGraphQL using JWT (JSON Web Tokens)
GNU General Public License v3.0
340 stars 74 forks source link

Data security question #175

Open catedm opened 1 year ago

catedm commented 1 year ago

Hey everyone,

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

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

LZL0 commented 1 year ago

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);
LZL0 commented 1 year ago

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.