使用WordPress wp_login钩子设置Cookie失败求助
Hey there, let's figure out why your ac-status cookie isn't sticking when users log in to your WordPress site. I've spotted a few key issues in your code and have a fixed version plus debugging tips to get this working:
Key Problems in Your Original Code
- Wrong Domain Format: You’re using
get_site_url()for the cookie domain, but this returns a full URL (likehttps://yourdomain.com). Thesetcookie()function expects just the bare domain (e.g.,yourdomain.comor.yourdomain.comfor subdomains). Using the full URL breaks the cookie’s domain matching, so browsers won’t store it. - Expiration Timestamp Error: Your third parameter is
365 * DAY_IN_SECONDS, which is a fixed timestamp from the Unix epoch (1970). That means the cookie is already expired the moment you set it! You need to add this value to the current time withtime() + 365 * DAY_IN_SECONDS. - Missing Security Attributes: Modern browsers block cookies without proper
Secure(for HTTPS sites) andSameSite-compatible settings. Skipping these can lead to the cookie being rejected, especially if your site uses HTTPS. - Headers Already Sent Risk: If your
api_connectfunction outputs any content (even accidental whitespace), it can send HTTP headers early. Once headers are sent,setcookie()can’t work because cookies are set via response headers.
Fixed Code Snippet
Here’s the revised version of your code with all these issues addressed:
// Adjust priority to 10 (default) to ensure it runs at the right time add_action('wp_login', array($this, 'knp_aci_login_check'), 10, 2); public function knp_aci_login_check( $user_login, $user ) { // First, make sure headers haven't been sent yet if (headers_sent()) { error_log('AC Status Cookie: Headers already sent - cannot set cookie'); return; } // Sanitize the user email to avoid URL/API issues $sanitized_email = urlencode(sanitize_email($user_login)); $contact = $this->request->api_connect('contacts?filters[email]='.$sanitized_email, 'GET'); if (wp_remote_retrieve_response_code( $contact ) == 200) { // Calculate expiration: 1 year from the current time $expiration = time() + 365 * DAY_IN_SECONDS; // Extract just the domain from your site URL (no protocol/path) $site_domain = wp_parse_url(get_site_url(), PHP_URL_HOST); // Use .yourdomain.com if you need the cookie to work across subdomains $cookie_domain = '.' . $site_domain; // Check if the site uses HTTPS to set the Secure attribute $is_secure = is_ssl(); // Set the cookie with all required attributes setcookie( 'ac-status', 'true', $expiration, '/', // Make cookie accessible across the entire site $cookie_domain, $is_secure, // Only send cookie over HTTPS if site uses it true // HttpOnly flag: blocks JS access to prevent XSS attacks (recommended) ); } }
Additional Debugging Tips
- Enable WordPress Debug: Add these lines to your
wp-config.phpto log errors:
Checkdefine('WP_DEBUG', true); define('WP_DEBUG_LOG', true);wp-content/debug.logfor any messages about headers being sent or cookie-related issues. - Test the API Response: Double-check that your
api_connectfunction is actually returning a 200 response. You can log the response code to confirm:error_log('API Response Code: ' . wp_remote_retrieve_response_code($contact)); - Check Browser Dev Tools: In your browser’s DevTools (Application tab in Chrome/Firefox), look at the Cookies section to see if the cookie is being set but marked as expired or blocked.
内容的提问来源于stack exchange,提问作者Alex Knopp
相关产品推荐
相关产品推荐

