If the request is not authenticated by the time it enters init
you can run your authentication logic if you wish.
If you want to be mindful of other plugins, you could run on init
with a priority of 0
as an example (or a negative value).
Plugins (may) hook onto init
at the default priority or a priority above the default and or another hook.
You won’t catch all edge cases.
Keep in mind, setting wp_set_auth_cookie
alone may not be enough.
The alternative is to hook into plugins_loaded
.
This (plugins_loaded
) is the earliest at which the method is_user_logged_in
becomes available.
Internally is_user_logged_in
looks as follows:
function is_user_logged_in() {
$user = wp_get_current_user();
return $user->exists();
}
I explain the mechanics of wp_get_current_user
below:
The global user object global $current_user
is first populated before init
.
Specifically in wp-settings.php
:
/**
* Fires after the theme is loaded.
*
* @since 3.0.0
*/
do_action( 'after_setup_theme' );
// Set up current user.
$GLOBALS['wp']->init();
/**
* Fires after WordPress has finished loading but before any headers are sent.
*
* Most of WP is loaded at this stage, and the user is authenticated. WP continues
* to load on the {@see 'init'} hook that follows (e.g. widgets), and many plugins instantiate
* themselves on it for all sorts of reasons (e.g. they need a user, a taxonomy, etc.).
*
* If you wish to plug an action once WP is loaded, use the {@see 'wp_loaded'} hook below.
*
* @since 1.5.0
*/
do_action( 'init' );
-
$GLOBALS['wp']->init();
callsWP::init
which callswp_get_current_user
which calls_wp_get_current_user
. -
_wp_get_current_user
populatesglobal $current_user
. -
_wp_get_current_user
fires the filterdetermine_current_user
.
function _wp_get_current_user() {
// ... shortened for brevity
$user_id = apply_filters( 'determine_current_user', false );
if ( ! $user_id ) {
wp_set_current_user( 0 );
return $current_user;
}
wp_set_current_user( $user_id );
return $current_user;
}
There are two default (core) callbacks that hooked onto determine_current_user
:
add_filter( 'determine_current_user', 'wp_validate_auth_cookie' );
add_filter( 'determine_current_user', 'wp_validate_logged_in_cookie', 20 );
This is essentially what validates the validity of the user’s authentication and if valid, determine_current_user
will return a corresponding user ID which finally gets passed to wp_set_current_user( $user_id )
.
Therefore you might be best off hooking onto plugins_loaded
:
function wpse_356655_custom_auth_callback() {
// ... shortened for brevity
$user_to_login = '...';
wp_set_auth_cookie( $user_to_login->ID, true );
// if you want is_user_logged_in to work you should set `wp_set_current_user` explicityly
wp_set_current_user( $user_to_login->ID );
do_action('wp_login', $user_to_login->name, $user_to_login );
}
add_action( 'plugins_loaded', 'wpse_356655_custom_auth_callback' );
You may also wish to look further into the wp_signon
core function, which may also suit your needs.
Update #1
In relation to your comment here
I cannot say this is the best approach but it is viable.
function wpse_356655_custom_auth_callback() {
// ... shortened for brevity
$user_to_login = '...';
wp_set_auth_cookie( $user_to_login->ID, true );
// if you want is_user_logged_in to work you should set `wp_set_current_user` explicityly
wp_set_current_user( $user_to_login->ID );
// from within this callback, hook on to `init`
add_action('init', function() use($user_to_login) {
do_action('wp_login', $user_to_login->name, $user_to_login );
});
}
add_action( 'plugins_loaded', 'wpse_356655_custom_auth_callback' );