hooks - is_user_logged_in() doesn't work after custom login and redirect

admin2025-01-07  5

I'm implimenting a simple magic link login feature and I've got it working nicely, however when the user is redirected to the homepage after being logged in the is_user_logged_in() still returns false, even though the login cookie is being set (confirmed via devtools). If I then refresh the page or navigate to another page the is_user_logged_in() then returns true.

Below is my code, I've removed all of the auth validation logic for simplicity:

// add login link rewrite rule
add_action('init', function () {
    add_rewrite_rule('login-link$', 'index.php?login_link=1', 'top');
});


// add login link query var
add_filter('query_vars', function ($query_vars) {
    $query_vars[] = 'login_link';
    return $query_vars;
});

// handle login link
add_action('parse_request', function (&$wp) {
    if (array_key_exists('login_link', $wp->query_vars)) {

        $user = // get user and validate hashed token from url...

        // login user
        wp_clear_auth_cookie();
        wp_set_current_user($user->ID);
        wp_set_auth_cookie($user->ID);
        do_action('wp_login', $user->user_login, $user);

        // redirect to home
        wp_safe_redirect(home_url());
        exit();
    }
});

The call to is_user_logged_in() is then happening inside the footer.php template file:

<?php if (is_user_logged_in()) : ?>
    <p>Logged in as <?php echo esc_html(wp_get_current_user()->user_email); ?></p>
<?php endif; ?>

My understanding is that the parse_request hook happens before the headers are sent, and the cookie is being saved in the browser, so I don't think that's the issue. Any ideas why this could be happening?

I'm implimenting a simple magic link login feature and I've got it working nicely, however when the user is redirected to the homepage after being logged in the is_user_logged_in() still returns false, even though the login cookie is being set (confirmed via devtools). If I then refresh the page or navigate to another page the is_user_logged_in() then returns true.

Below is my code, I've removed all of the auth validation logic for simplicity:

// add login link rewrite rule
add_action('init', function () {
    add_rewrite_rule('login-link$', 'index.php?login_link=1', 'top');
});


// add login link query var
add_filter('query_vars', function ($query_vars) {
    $query_vars[] = 'login_link';
    return $query_vars;
});

// handle login link
add_action('parse_request', function (&$wp) {
    if (array_key_exists('login_link', $wp->query_vars)) {

        $user = // get user and validate hashed token from url...

        // login user
        wp_clear_auth_cookie();
        wp_set_current_user($user->ID);
        wp_set_auth_cookie($user->ID);
        do_action('wp_login', $user->user_login, $user);

        // redirect to home
        wp_safe_redirect(home_url());
        exit();
    }
});

The call to is_user_logged_in() is then happening inside the footer.php template file:

<?php if (is_user_logged_in()) : ?>
    <p>Logged in as <?php echo esc_html(wp_get_current_user()->user_email); ?></p>
<?php endif; ?>

My understanding is that the parse_request hook happens before the headers are sent, and the cookie is being saved in the browser, so I don't think that's the issue. Any ideas why this could be happening?

Share Improve this question asked Dec 18, 2024 at 15:27 Cam ParryCam Parry 11 bronze badge 1
  • try without 'wp_clear_auth_cookie'. on my test site I made a plugin which works with "wp_set_auth_cookie" followed by a redirection. – mmm Commented Dec 18, 2024 at 20:07
Add a comment  | 

1 Answer 1

Reset to default 1

The issue arises because the is_user_logged_in() function relies on the authentication cookies being recognized by the WordPress request lifecycle. When you set the authentication cookies using wp_set_auth_cookie(), they are sent to the browser, but they are not yet available to the same request that initiated the cookie setting. The cookies will only be recognized on subsequent requests.

// Handle login link
add_action('parse_request', function (&$wp) {
    if (array_key_exists('login_link', $wp->query_vars)) {
        $user = // get user and validate hashed token from url...

        // Log in the user
        wp_clear_auth_cookie();
        wp_set_current_user($user->ID);
        wp_set_auth_cookie($user->ID);

        // Set the global $current_user manually for the current request
        global $current_user;
        $current_user = $user;

        do_action('wp_login', $user->user_login, $user);

        // Redirect to home
        wp_safe_redirect(home_url());
        exit();
    }
});

1).global $current_user; $current_user = $user;: This ensures that the global $current_user variable is set for the current request.

2). wp_set_current_user($user->ID);: Even though you've already set the user in wp_set_auth_cookie(), this ensures that WordPress internally knows about the current user for this request.

By doing this, is_user_logged_in() will correctly recognize the logged-in status for the current request.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1736258246a498.html

最新回复(0)