Joy
(@joyously)
You can look at https://codex.ww.wp.xz.cn/Plugin_API/Action_Reference for an order that actions are run. (this is an old and partial list)
If a plugin tries to do something out of order, it usually doesn’t work. Remember that the authentication functions are pluggable, but called at a specific point in the load order.
You should ask the plugin author to check that the plugin works when the user is not logged in.
Thank you for the pointer. I had been looking at it, as well as this one.
In this case, it works, until the 2nd plugin tries to use the application_password_is_api_request filter and then it doesn’t. I guess it’s not clear (to me) whether the first plugin is calling wp_create_nonce() too early, or whether the second plugin is setting the application_password_is_api_request filter too late.
As far as I understand, WP does not enforce when user authentication can or cannot happen.
Joy
(@joyously)
As far as I understand, WP does not enforce when user authentication can or cannot happen.
Plugins rely on the functions that WP provides to do the authentication. But as I said,
Remember that the authentication functions are pluggable, but called at a specific point in the load order.
You can’t call functions that have user data before the user is authenticated. Well, you can, but it won’t work right.
If a user is logged in at all, that user is established just before the “init” action. Any code that runs before this that relies upon a logged in user will likely fail.
Thank you for all the responses.
I found out how the REST API handles the (premature) user authentication issue in wp-includes/rest-api/class-wp-rest-server.php:
public function serve_request( $path = null ) {
/* @var WP_User|null $current_user */
global $current_user;
if ( $current_user instanceof WP_User && ! $current_user->exists() ) {
/*
* If there is no current user authenticated via other means, clear
* the cached lack of user, so that an authenticate check can set it
* properly.
*
* This is done because for authentications such as Application
* Passwords, we don't want it to be accepted unless the current HTTP
* request is a REST API request, which can't always be identified early
* enough in evaluation.
*/
$current_user = null;
}