Suppose you register the following endpoint in your application on example.org
:
register_rest_route(
'sample/v1',
'/test',
[
[
'methods' => 'POST',
'permission_callback' => [
TestsController::class,
'permission_check'
],
'callback' => [
TestsController::class,
'run'
],
'args' => [
'id' => [
'type' => 'integer',
'description' => 'Identifier of the request',
'required' => true
]
]
]
]
);
With the contents of TestController
being:
final class TestsController
{
/**
* @param WP_REST_Request $request
*
* @return WP_REST_Response
*/
public static function run( WP_REST_Request $request ): WP_REST_Response
{
// This is just a test, nothing is done here
return new WP_REST_Response(
[
'success' => true,
'message' => 'All good!'
],
200
);
}
/**
* @param WP_REST_Request $request
*
* @return bool
*/
public static function permission_check( WP_REST_Request $request ): bool
{
return true;
}
}
A few months ago, I've asked how you can validate requests incoming to your custom WordPress REST API endpoints via the JSON Schema you specified when doing register_rest_route
. Back then, the answer was by specifying the validate_callback
parameter for every single request argument, specified in args
. When you however do the above-mentioned and send a request with no or an invalid payload, validation automatically takes place, and you get an according 400
error back. Has WP Core been updated to do JSON Schema - based request argument validation automatically now?
Regarding the permission_callback
argument of the endpoint, the docs mention that:
Note that the permission callback also receives the Request object as the first parameter, so you can do checks based on request arguments if you need to.
I suppose that this means that WordPress does payload validation before calling your permission_callback
?
Finally, suppose you have a website which uses a custom login system, hence which does not rely on WordPress cookies for the Frontend. This would then mean that WordPress would provide information about why a payload is bad to unauthenticated clients, which does not seem preferential to me.
Further down in the above-linked docs, and I suppose exactly due to this problem; I found the following note:
Once you register a permission_callback, you will need to authenticate your requests (for example by including a nonce parameter) or you will receive a rest_forbidden error.
This however does not seem to be true. Try registering my test endpoint above, and fire a request from any HTTP client, for example:
POST https://example.org/wp-json/sample/v1/test
Content-Type: application/json
{
"id":"hello"
}
You will not get any rest_forbidden
error, but a rest_missing_callback_param
error with the details explaining why your payload is invalid. This by the way again happens automatically now, without the provision of validate_callback
to your id
argument. Hence I wonder if WordPress does any kind of REST authentication by default?
Due to all of this, my final question is: Does WordPress provide a hook or a filter which allows you to do an authentication which relies on your own cookie / token logic, before the payload gets validated / before you step into authorization? Such that these steps only get executed if your authentication
is passed? Something in the sense of:
register_rest_route(
'sample/v1',
'/test',
[
[
'methods' => 'POST',
// This would then get executed before anything else
'authentication_callback' => [
TestsController::class,
'authentication_check'
],
'permission_callback' => [
TestsController::class,
'permission_check'
],
'callback' => [
TestsController::class,
'run'
],
'args' => [
'id' => [
'type' => 'integer',
'description' => 'Identifier of the request',
'required' => true
]
]
]
]
);
You may also imagine what I need as an implementation of the documented rest_authentication_errors filter, but on a per-endpoint specific level.