Building a member area on Core dna: who a member is in the data, the sign-in flows and their templates, single sign-on and passkeys, the my-account routing convention, members-only content, sessions and the page cache, and the security checks to run before launch.
L2
Unit 06 · Sessions, cookies and the cache
Sign-in sessions and cookies
Sessions, cookies and the cachePage 32 of 36Updated
A member's sign-in is one cookie holding an access token that lasts twelve hours; a second cookie carries the working session. Their attributes, what SameSite does to visitors arriving from other sites, cookie or bearer token for scripts, and what a member sees when either runs out mid-form.
Who this is for. The theme and JavaScript developers on a member site, and whoever is asked why a member "was logged out at random". Afterwards you know what each cookie does, how long a sign-in lasts, and how to keep a member's work when it ends.
What a sign-in is
Signing in sets a cookie called token. Its value is an OAuth access token, beginning CDNA-A-, the same kind an API client sends as a bearer token, and it is the whole sign-in: every request is authenticated from it.
Attribute
Value
What it means
Secure
Set
Sent over HTTPS only
HttpOnly
Set
Scripts on the page cannot read it, so a script injected into a page cannot steal the sign-in
SameSite
Lax
Not sent with a form posted from another site, or inside another site's iframe (below)
Domain
The exact hostname signed in on
Signing in on www.example.com does not sign the member in on shop.example.com
Lifetime
Twelve hours from sign-in
Fixed: activity does not extend it
The sign-in ends when the twelve hours are up, when the member signs out at /logout (in that browser only), when they end it from their list of signed-in sessions (Signed-in sessions), or when the password changes, which ends the other sessions, apart from a device kept signed in with Remember me, and keeps the current one. Where remember-me is on, a provider sign-in can be renewed without the member noticing (Remember me).
The other cookies
Cookie
Holds
Lifetime
PHPSESSID
The PHP session: the CSRF token, and the page to return to after signing in
Set by the server's configuration
cart
The visitor's cart, signed in or not
180 days by default (the Carts lifetime setting); Secure, HttpOnly, SameSite=Lax
remember_me
A renewal token, only when remember-me is switched on
30 days by default; set like token
dxpmessages-user, dxpmessages
Messages waiting to be shown after a redirect, such as "Profile Updated"
Until shown
A template can set a cookie of its own with $_response->setCookie(name, value, expiry); the expiry takes a timestamp or a string such as '+30 days'. Such cookies are HttpOnly and SameSite=Lax, are marked Secure when the request is over HTTPS, and cannot be called PHPSESSID. The platform's own cookie attributes are fixed: a site cannot change them.
SameSite and arriving from another site
A Lax cookie is sent when a visitor follows a link to your site from anywhere, and is not sent when another site posts a form to yours, nor on requests made from inside another site's page. For a member site that means:
A link from an email or a partner site arrives signed in and with the cart, as expected.
A form posted to your site from another site, such as a payment provider returning the visitor with a POST, arrives without the session and without the cart. The request is handled as a signed-out visitor with no cart, which looks to the member like a cart that emptied or a sign-in that vanished. Design such return steps to work from the data in the request, an order or submission reference, and land the visitor on a page that loads with their cookies.
A site shown inside another site's iframe cannot keep anyone signed in.
Cookie or bearer token
Client
Use
A script on the site's own pages, calling routes on the same site
The cookie, which the browser sends by itself. On a POST, PUT, PATCH or DELETE, send the CSRF token as an X-Csrf-Token header
Anything else: a server, a mobile app, a front end on another domain
Authorization: Bearer, with an OAuth access token, or an API key, the older option (Choosing one)
A request with an Authorization header is never CSRF-checked. The platform sends no cross-origin headers, so a browser on another domain cannot read the site's responses at all: that client calls from its own server. A member's cookie reaches the routes built for visitors and members (the member area, the profile, the cart and checkout, form submission), not the REST API in general (A site member and a backend user).
Neither changes how the page cache is read: a stored copy is served whatever the request carries. Both make the request signed in, so its response is never stored. A bearer header, like the PHPSESSID cookie a signed-in member carries, also makes the platform skip its shared Memcached layer for that request (The Memcached half).
For a script on an uncached page, the token can travel in a meta tag. On a cached page the stored copy has no token, so deliver it in a fragment instead (below):
const form = document.querySelector('#address-form');
fetch('/my-account/address', {
method: 'POST',
headers: { 'X-Csrf-Token': document.querySelector('meta[name=csrf-token]').content },
body: new FormData(form),
});
Two clocks
A member's work depends on two things that expire separately, and each fails differently:
What runs out
When
What the member sees
The sign-in, the token cookie
Twelve hours after signing in
The next request to a members-only page redirects to /login. A form posted at that moment is lost: after signing in they are returned to the form's URL, empty
The PHP session
When the browser discards it, or the server clears it after a period of inactivity
Still signed in, but the CSRF token in the open form belonged to the old session, so the submit is refused with a 403, "Missing or invalid CSRF token". Your site's errors/not-authorized.html is shown if it has one
Neither is random. A member who "keeps getting logged out" usually signs in once in the morning and works into the evening, or leaves a long form open over lunch.
When a session runs out mid-form
For any long form in a member area, make the loss recoverable rather than final:
Save a draft in the browser as the member types, restore it when the form loads, and clear it on the page the form leads to on success.
Give errors/not-authorized.html a plain explanation ("Your session expired. Your answers are saved: go back and send the form again.") and a link back, instead of "Access denied".
Keep secrets out of the draft: passwords, the CSRF token, files, and on a site used from shared computers, anything personal.
JavaScriptA draft that survives an expired session
const form = document.querySelector('form[data-draft]');
if (form) {
const key = 'draft:' + form.dataset.draft;
const keep = (el) => el.name && !['password', 'hidden', 'file'].includes(el.type);
const saved = JSON.parse(localStorage.getItem(key) || '{}');
for (const el of form.elements) {
if (keep(el) && el.name in saved) el.value = saved[el.name];
}
form.addEventListener('input', () => {
const data = {};
for (const el of form.elements) if (keep(el)) data[el.name] = el.value;
localStorage.setItem(key, JSON.stringify(data));
});
}
// On the success page: <div data-clear-draft="application"></div>
document.querySelectorAll('[data-clear-draft]').forEach((el) => {
localStorage.removeItem('draft:' + el.dataset.clearDraft);
});
The form carries data-draft="application". Clearing on the success page rather than on submit keeps the draft when the submit is refused, which is the case it exists for. Wrap the storage calls in try where the site must work in browsers that block storage.
A member site and the page cache
The page cache is read before the platform looks at any cookie, so a member who opens a public page that an anonymous visitor has already requested is served the anonymous copy: a header that says "Sign in", no personal content, no CSRF token, and no pre-filled form fields. Nothing rendered for a signed-in member is stored. Personal parts of public pages therefore arrive as fragments; Member pages and the page cache covers the rule, how to measure it and the pattern.