Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversHalloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
World desk9 min

WordPress Cookies and PHP Sessions Explained: Authentication, Security, and REST Nonces

WordPress relies on authentication cookies for normal login state. This guide explains cookie names and lifetimes, PHP-session trade-offs, secure plugin implementation, cache pitfalls, and why REST requests still need nonces.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
// 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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

  • Use HTTPS for the complete authenticated flow. Set the Secure attribute so a session identifier is not sent over cleartext HTTP. Redirecting only the login form while serving authenticated pages over HTTP is insufficient.
  • Set HttpOnly when 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. Lax is a practical default for many sites; Strict is 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.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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.

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

  1. Identify whether you need WordPress’s logged-in user identity or separate temporary workflow state.
  2. For ordinary login state, use WordPress’s authentication APIs and default cookie flow.
  3. If adding a custom session, document its data, idle timeout, absolute timeout, storage backend, and logout invalidation before implementation.
  4. Serve authenticated traffic over HTTPS and set Secure, HttpOnly, and an appropriate SameSite policy.
  5. Regenerate the identifier after login and privilege changes.
  6. Add CSRF protection: WordPress REST nonces for cookie-authenticated REST requests, plus capability checks and input validation.
  7. Exclude login and personalized responses from public full-page caches and test the complete proxy/CDN path.
  8. 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.