WordPress normally uses signed browser cookies—not PHP sessions—to keep users logged in. The browser sends those cookies with matching requests, while WordPress verifies them and loads the user account. A PHP session is a different pattern: the browser usually stores only an identifier and the actual state remains in a server-side session store. Use WordPress’s built-in authentication cookies for ordinary logins; add a carefully designed server-side session only when a plugin has state that cannot be represented by WordPress authentication and user metadata.
Antihost offers managed WordPress hosting with free migration, one-click staging and a 14-day free trial.
The distinction matters for lifetime, logout, caching, horizontal scaling, CSRF protection, and the damage caused if a bearer credential is stolen.
As an Amazon Associate I earn from qualifying purchases.
What a WordPress cookie is and what it does
A cookie is a small value that a website asks the browser to store. On later requests, the browser sends that value when the cookie’s domain, path, security, and SameSite rules allow it. WordPress uses cookies to verify identity, remember preferences, support comments, detect browser capabilities, and maintain login state.
The value is held on the client, so it must be treated as potentially observable and replayable. A cookie that functions as an authentication credential is a bearer credential: whoever obtains a valid value may be able to use the associated session until it expires or the server invalidates it. Do not put passwords, API secrets, or sensitive personal information directly in an unsigned cookie.
#1 Best Overall
Core WordPress authentication cookies
| Cookie | Typical role |
|---|---|
wordpress_[hash] |
Authentication for the WordPress administration area. |
wordpress_logged_in_[hash] |
Indicates that a visitor is logged in when viewing the front end. |
wordpress_sec_[hash] |
Used for secure HTTPS login authentication. |
The [hash] portion varies by site configuration; it is not a literal string that you type. WordPress also sets non-authentication cookies for settings, comments, language or localization, and capability testing. Their exact names and behavior can vary with enabled features, plugins, and the site’s configuration.
How WordPress login cookies are created and expire
The normal WordPress login flow establishes cookie authentication automatically. In plugin code that must authenticate a user programmatically, use the supported wp_set_auth_cookie() function rather than the obsolete API.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitches// Example after you have securely verified the user and obtained the ID.
wp_set_auth_cookie( $user_id, $remember, is_ssl() );
The first argument is the user ID. The second controls persistence, and the third requests a secure cookie when the connection is HTTPS. Your code still needs to perform authentication and authorization correctly before calling this function; setting a cookie does not prove that a person should be logged in.
Rank #2
Default lifetimes
| Login choice | Default persistence | What it means |
|---|---|---|
Remember Me selected ($remember = true) |
14 days | The authentication cookie is persistent by default and survives browser restarts for that period, subject to WordPress filters and site behavior. |
Remember Me not selected ($remember = false) |
2 days (48 hours) | The normal authentication expiration is two days. The browser may treat the cookie as a session cookie, while WordPress still applies its authentication expiration rules. |
These are WordPress Developer Resources’ current default values. A site or plugin can alter expiration through supported filters, and a user may be logged out earlier by a password change, explicit logout, administrator action, or server-side invalidation. Never describe the defaults as a guarantee for every installation.
wp_setcookie() is the older API and has been deprecated since WordPress 2.5.0. New code should use wp_set_auth_cookie() and the current authentication hooks and filters.
PHP sessions: the different state model
A PHP session associates a random session identifier with state stored on the server. PHP commonly sends the identifier in a browser cookie (often named PHPSESSID), but the sensitive values—checkout progress, a temporary workflow, or a short-lived token—remain in a server-side session store. The browser normally holds only the identifier.
This model reduces the amount of sensitive data exposed to the client, but it introduces server-side lifecycle and infrastructure work. The store must be available to every web server that may handle a request, or requests must be routed consistently. File-based sessions on one server can fail after load balancing unless the files are shared or a centralized store is configured.
WordPress cookies versus a custom PHP session
| Decision axis | WordPress authentication cookie | Custom PHP session |
|---|---|---|
| Where state lives | Authentication information is represented in cookies that WordPress verifies; user data remains in WordPress. | State is kept in a server-side session store; the client normally has only an identifier. |
| Framework integration | Built into WordPress login, user APIs, capability checks, and common admin/front-end flows. | Not a WordPress default; your plugin must define startup, storage, expiration, and cleanup behavior. |
| Lifetime and renewal | WordPress defaults to two days without Remember Me and 14 days with it, with filters and events able to change behavior. | Your application chooses idle and absolute timeouts, renewal rules, and cleanup. |
| Invalidation | WordPress logout and authentication controls can invalidate the login; deleting a browser cookie alone is not a complete revocation strategy for any stolen bearer value. | Destroy or revoke server-side state, then expire the browser identifier. Server-side invalidation can stop a stolen identifier immediately. |
| CSRF requirements | Cookie-authenticated state-changing requests need WordPress nonces as well as capability checks. | Still requires CSRF defenses for browser requests; a session does not remove that requirement. |
| Cache interaction | Responses that vary by login cookies must not be served from a cache as if they were public. | Session-started responses also vary by the session identifier and need equivalent cache controls. |
| Horizontal scaling | Verification is designed around WordPress’s own authentication system and shared site configuration. | All application servers need the same session store or reliable session affinity. |
| If a bearer value is stolen | A stolen valid authentication cookie can be replayed until expiration or invalidation. | A stolen session identifier can be replayed until expiration or server-side revocation, even though the data itself stays on the server. |
When a plugin should use WordPress authentication
If the requirement is “is this visitor logged in?” or “which WordPress user is making this request?”, use WordPress authentication cookies and APIs. They integrate with is_user_logged_in(), the current user object, roles, capabilities, admin screens, and the normal login/logout flow. Do not create a second login session merely to duplicate information WordPress already maintains.
Use a custom server-side session only for genuinely temporary, per-visitor state that does not belong in user metadata, a signed short-lived token, or another purpose-built store. Examples can include a multi-step operation for an otherwise anonymous visitor or transient workflow data that must not be placed in a client cookie. Define the data, maximum lifetime, cleanup policy, and logout behavior before writing code.
Rank #4
Why casual session_start() calls cause trouble
Calling session_start() in a theme or plugin without an architecture can send headers after output has already begun, trigger “headers already sent” failures, lock a session during concurrent requests, and make full-page caching ineffective. It also creates state where WordPress cookies may already solve the requirement.
Free tools Windows power users keep installed
One-click scans. No signup required.
If a custom session is justified, start it early—before any output and at a predictable hook—then verify that the hosting stack, cache, CDN, and object-cache strategy support it. A session identifier must have a defined path, domain, expiration, and security attributes, and the server-side store must be reachable from every application node.
Secure cookie and session settings
Security controls work together; none makes an exposed credential harmless.
Best Value
- Use HTTPS for the complete authenticated flow. Set the
Secureattribute so a session identifier is not sent over cleartext HTTP. Redirecting only the login form while serving authenticated pages over HTTP is insufficient. - Set
HttpOnlywhen JavaScript does not need the identifier. This blocks ordinary script access and limits exposure from some script-based theft, but it does not fix an existing cross-site scripting vulnerability. - Choose an appropriate SameSite value.
Laxis a practical default for many sites;Strictis stronger but can affect cross-site navigation and integrations. SameSite is defense in depth, not a replacement for CSRF tokens. - Rotate identifiers after authentication and privilege changes. Regeneration helps prevent session fixation, in which an attacker gets a victim to use an identifier known to the attacker.
- Invalidate server state on logout and high-risk events. Password changes, account recovery, suspected compromise, and privilege changes are reasons to revoke sessions. Expiring a cookie in the browser does not revoke a copied identifier that is still accepted by the server.
- Minimize cookie scope. Use the narrowest practical domain and path, and avoid exposing an administrative credential to unrelated subdomains.
- Keep secrets out of unsigned client values. If a client-held value must carry information, authenticate and integrity-protect it and keep its contents minimal; otherwise store the data server-side.
Why the WordPress REST API needs a nonce when you are logged in
WordPress cookie authentication is established by the normal login flow, so a browser automatically sends the login cookie with a same-site REST request. That cookie proves which browser session is being presented, but it does not prove that the request originated from your site rather than from a malicious page that induced the browser to send its cookies.
For REST requests made while logged in, WordPress therefore requires a REST nonce. Send it in the X-WP-Nonce header or the _wpnonce request parameter, depending on the API usage. Without a valid nonce, WordPress treats the request as unauthenticated even when a login cookie is present.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →fetch('/wp-json/example/v1/item', {
method: 'POST',
headers: {
'X-WP-Nonce': window.wpApiSettings.nonce,
'Content-Type': 'application/json'
},
body: JSON.stringify({ title: 'Example' })
});
A nonce is an anti-CSRF value, not a password and not an authorization grant. It does not replace a REST route’s permission callback or capability check. The endpoint must still verify that the current user may perform the requested action, validate and sanitize input, and return an appropriate error when permission fails.
Caching, proxies, and cookie-varying responses
Public full-page caches should not serve one visitor’s authenticated HTML to another visitor. Exclude login and cookie-varying responses from full-page caching; WordPress’s login guidance specifically calls out wp-login.php and cookie-based sessions when configuring server caching.
Audit every layer: the WordPress page-cache plugin, reverse proxy, CDN, and host-level cache. A response can be incorrectly cached even when PHP itself handled the request correctly. For APIs, configure cache keys and headers so private responses are not stored or replayed as public content.
Quick Recap
Troubleshooting common failures
| Symptom | Likely cause | Fix to check first |
|---|---|---|
| User logs in, then immediately appears logged out | Mixed HTTP/HTTPS, an incorrect secure-cookie setting, clock or domain mismatch, or a cache serving a public response. | Force HTTPS throughout the flow, inspect cookie domain/path and Secure flags, then bypass page caches for the login and authenticated pages. |
| REST request returns an authentication or permission error | Missing, expired, or incorrectly named nonce; the request may also lack the required capability. | Send the current nonce as X-WP-Nonce or _wpnonce, then inspect the route’s permission callback and the logged-in user’s capability. |
| “Headers already sent” after adding sessions | session_start() ran after output, whitespace, or a buffer flush. |
Move session initialization to an early, controlled hook before output and remove accidental output; reconsider whether a PHP session is needed. |
| Sessions disappear only behind a load balancer | Each server has a different local session store, or session affinity is unreliable. | Use a shared session store available to every node, or redesign the state flow; do not assume local files are shared. |
| Logout does not stop a previously copied identifier | Only the browser cookie was deleted. | Revoke or destroy the corresponding server-side session or WordPress authentication state, then expire the client cookie. |
A practical decision checklist
- Identify whether you need WordPress’s logged-in user identity or separate temporary workflow state.
- For ordinary login state, use WordPress’s authentication APIs and default cookie flow.
- If adding a custom session, document its data, idle timeout, absolute timeout, storage backend, and logout invalidation before implementation.
- Serve authenticated traffic over HTTPS and set Secure, HttpOnly, and an appropriate SameSite policy.
- Regenerate the identifier after login and privilege changes.
- Add CSRF protection: WordPress REST nonces for cookie-authenticated REST requests, plus capability checks and input validation.
- Exclude login and personalized responses from public full-page caches and test the complete proxy/CDN path.
- Test logout, password changes, expired sessions, multiple servers, and a stolen-identifier scenario in a staging environment.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.




