Preventing unauthenticated requests to your WPGraphQL API
By Jason Bahl
January 30th, 2019
Someone asked in the Slack channel how they could lock down the WPGraphQL endpoint so that only authenticated users could access it.
Provided Solution
What this does
Below, I’ll walk through what this snippet does.
Hook into the GraphQL request lifecycle
This snippet hooks into do_graphql_request
, which is fired when a GraphQL request is about to be executed, and fires the function force_graphql_api_authentication
The action passes 4 args to force_graphql_api_authentication
$query
$operation
$variables
$params
For this particular case, we only care about the first argument$query
which is the query string to be executed.
Determine if the request is an HTTP Request
Since WPGraphQL can be used internally within your Plugin and Theme PHP code to hydrate data for page templates, shortcodes, etc, locking down all GraphQL requests could have unintentional consequences, so we don’t want to prevent all unauthenticated requests from executing with GraphQL, we just want to prevent unauthenticated requests coming over HTTP.
So we first check:
This checks to see if the request is indeed a GraphQL HTTP Request. If it’s not, it simply returns and we let GraphQL carry on as usual. That means internal GraphQL requests using the graphql()
function can be processed as usual.
Ignore Introspection Queries
GraphQL has an awesome feature where the Schema itself is queryable. Tools such as WPGraphiQL, GraphQL Playground and Altair make use of the IntrospectionQuery to fetch the Schema and render Schema documentation for users.
Here we use a helper method from the underlying GraphQL PHP library which is part of WPGraphQL to get the Introspection Query.
Then, we compare the incoming query, which is passed through the do_graphql_request
action to check if the incoming query is an IntrospectionQuery or not:
And last, if we’ve determined that the incoming query is indeed an IntrospectionQuery, we return and allow GraphQL to execute as normal. This will allow GraphQL to execute the Introspection Query and send the Schema back to the tool requesting it.
Throw an error if the request is not authenticated
Lastly, we check to see if the request is authenticated by checking for the ID of the current user. If the ID is “0”, then the request is not authenticated, so we want to throw an error.
Conclusion
With this snippet, you can lock down your WPGraphQL endpoint so nothing will be executed if the request is not authenticated.
If you need to make authenticated requests, we recommend using WPGraphQL JWT Authentication, but any of the Auth plugins that work for the REST API plugin _should_ work well with WPGraphQL as well.
NOTE:
The Application Passwords plugin requires a filter to play nice with WPGraphQL: