[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-sanctum-cookie-sessions-vs-bearer-tokens":3,"blog-nav-sanctum-cookie-sessions-vs-bearer-tokens":27},{"slug":4,"title":5,"description":6,"body":7,"category":8,"readTime":9,"tags":10,"coverImage":14,"coverImageAlt":15,"heroImage":16,"heroImageAlt":15,"metaTitle":17,"metaDescription":18,"ogImage":19,"noindex":20,"published":21,"publishAt":22,"sortOrder":23,"updatedAt":22,"status":24,"path":25,"bodyHtml":26},"sanctum-cookie-sessions-vs-bearer-tokens","Cookie sessions or bearer tokens for a Nuxt and Laravel app","A first-party Nuxt app should use a Sanctum cookie session. Bearer tokens belong to mobile apps and other clients, and they must be revocable.","[Security basics for Philippine SME apps](\u002Fblog\u002Fsecurity-basics-ph-sme-apps) covers unique logins, MFA, and session timeouts. It does not say where the session lives. For a Nuxt app talking to Laravel, that choice is a cookie or a bearer token.\n\nLaravel Sanctum documents both. The [SPA authentication](https:\u002F\u002Flaravel.com\u002Fdocs\u002F13.x\u002Fsanctum#spa-authentication) flow is the cookie. API tokens are the other client.\n\n## Use the cookie when the browser is yours\n\nA first-party Nuxt app on the same site — or on a domain you have configured as stateful — should use the cookie session. The cookie is httpOnly. The page’s JavaScript does not need to read it. CSRF protection is the tradeoff Sanctum’s SPA notes walk through, and it is the right tradeoff for an app you control.\n\n[How we build](\u002Fblog\u002Fhow-we-build-scalable-web-applications) is one Laravel backend and a Nuxt client. That client should not be holding a long-lived bearer token in local storage because a tutorial did. A token the page can read is a token an injected script can read.\n\n## Use a token when the client is not the site\n\nA phone app, a partner, a script. Issue a token, scope what it can call, and be able to revoke it without logging every browser out. [API-first backends](\u002Fblog\u002Fapi-first-backends-for-mobile) treat mobile as a client of the same rules. A token is how that client authenticates. It is not a reason to skip revocation, and it is not the staff session cookie reused in an app binary.\n\n## What we will not do\n\n- One never-expiring token shared by the admin and the public site.\n- CSRF turned off because “the frontend and the API are both ours.”\n- A separate auth service before Sanctum is actually the wrong tool. For this shape of app, it usually is not.\n\nSession timeout and MFA from the security-basics article still apply. They sit on top of this choice. They do not replace it.\n\n## Straight next step\n\nIf the admin and the public site share one long-lived token, [tell us where it is stored](\u002Fcontact). We will move the first-party browser onto a cookie session and leave tokens for clients that are not the site.","Engineering",6,[11,12,13],"Auth","Laravel","Nuxt","\u002Fimages\u002Fjournal\u002Fsanctum-cookie-sessions-vs-bearer-tokens-cover.webp?v=20261013b","Person at a laptop in an office","\u002Fimages\u002Fjournal\u002Fsanctum-cookie-sessions-vs-bearer-tokens-hero.webp?v=20261013b","Cookie Sessions vs Bearer Tokens | PrimeCode","When a Nuxt and Laravel app should use Sanctum cookie sessions, and when a bearer token is the right client.","\u002Fimages\u002Fjournal\u002Fsanctum-cookie-sessions-vs-bearer-tokens-og.webp?v=20261013b",false,true,"2026-10-23T01:00:00.000Z",55,"live","\u002Fblog\u002Fsanctum-cookie-sessions-vs-bearer-tokens","\u003Cp>\u003Ca href=\"\u002Fblog\u002Fsecurity-basics-ph-sme-apps\" rel=\"noopener noreferrer\">Security basics for Philippine SME apps\u003C\u002Fa> covers unique logins, MFA, and session timeouts. It does not say where the session lives. For a Nuxt app talking to Laravel, that choice is a cookie or a bearer token.\u003C\u002Fp>\n\u003Cp>Laravel Sanctum documents both. The \u003Ca href=\"https:\u002F\u002Flaravel.com\u002Fdocs\u002F13.x\u002Fsanctum#spa-authentication\" rel=\"noopener noreferrer\">SPA authentication\u003C\u002Fa> flow is the cookie. API tokens are the other client.\u003C\u002Fp>\n\u003Ch2>Use the cookie when the browser is yours\u003C\u002Fh2>\n\u003Cp>A first-party Nuxt app on the same site — or on a domain you have configured as stateful — should use the cookie session. The cookie is httpOnly. The page’s JavaScript does not need to read it. CSRF protection is the tradeoff Sanctum’s SPA notes walk through, and it is the right tradeoff for an app you control.\u003C\u002Fp>\n\u003Cp>\u003Ca href=\"\u002Fblog\u002Fhow-we-build-scalable-web-applications\" rel=\"noopener noreferrer\">How we build\u003C\u002Fa> is one Laravel backend and a Nuxt client. That client should not be holding a long-lived bearer token in local storage because a tutorial did. A token the page can read is a token an injected script can read.\u003C\u002Fp>\n\u003Ch2>Use a token when the client is not the site\u003C\u002Fh2>\n\u003Cp>A phone app, a partner, a script. Issue a token, scope what it can call, and be able to revoke it without logging every browser out. \u003Ca href=\"\u002Fblog\u002Fapi-first-backends-for-mobile\" rel=\"noopener noreferrer\">API-first backends\u003C\u002Fa> treat mobile as a client of the same rules. A token is how that client authenticates. It is not a reason to skip revocation, and it is not the staff session cookie reused in an app binary.\u003C\u002Fp>\n\u003Ch2>What we will not do\u003C\u002Fh2>\n\u003Cul>\n\u003Cli>One never-expiring token shared by the admin and the public site.\u003C\u002Fli>\n\u003Cli>CSRF turned off because “the frontend and the API are both ours.”\u003C\u002Fli>\n\u003Cli>A separate auth service before Sanctum is actually the wrong tool. For this shape of app, it usually is not.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003Cp>Session timeout and MFA from the security-basics article still apply. They sit on top of this choice. They do not replace it.\u003C\u002Fp>\n\u003Ch2>Straight next step\u003C\u002Fh2>\n\u003Cp>If the admin and the public site share one long-lived token, \u003Ca href=\"\u002Fcontact\" rel=\"noopener noreferrer\">tell us where it is stored\u003C\u002Fa>. We will move the first-party browser onto a cookie session and leave tokens for clients that are not the site.\u003C\u002Fp>\n",{"prev":28,"related":46},{"slug":29,"title":30,"description":31,"category":8,"readTime":32,"tags":33,"coverImage":37,"coverImageAlt":38,"heroImage":39,"heroImageAlt":38,"metaTitle":40,"metaDescription":41,"ogImage":42,"noindex":20,"published":21,"publishAt":43,"sortOrder":44,"updatedAt":43,"status":24,"path":45},"prevent-double-booking-reservation-concurrency","How a reservation system prevents double booking","Two requests can both read a free slot. A unique or exclusion constraint, plus a hold that expires, is what rejects the second insert.",7,[34,35,36],"Bookings","Database","Concurrency","\u002Fimages\u002Fjournal\u002Fprevent-double-booking-reservation-concurrency-cover.webp?v=20261013b","Open calendar planner with a coffee cup","\u002Fimages\u002Fjournal\u002Fprevent-double-booking-reservation-concurrency-hero.webp?v=20261013b","Preventing Double Bookings in a Reservation System | PrimeCode","Why two simultaneous bookings both see a free slot, and how a constraint and a short hold stop the duplicate.","\u002Fimages\u002Fjournal\u002Fprevent-double-booking-reservation-concurrency-og.webp?v=20261013b","2026-10-21T01:00:00.000Z",54,"\u002Fblog\u002Fprevent-double-booking-reservation-concurrency",[47,49,65],{"slug":29,"title":30,"description":31,"category":8,"readTime":32,"tags":48,"coverImage":37,"coverImageAlt":38,"heroImage":39,"heroImageAlt":38,"metaTitle":40,"metaDescription":41,"ogImage":42,"noindex":20,"published":21,"publishAt":43,"sortOrder":44,"updatedAt":43,"status":24,"path":45},[34,35,36],{"slug":50,"title":51,"description":52,"category":8,"readTime":9,"tags":53,"coverImage":56,"coverImageAlt":57,"heroImage":58,"heroImageAlt":57,"metaTitle":59,"metaDescription":60,"ogImage":61,"noindex":20,"published":21,"publishAt":62,"sortOrder":63,"updatedAt":62,"status":24,"path":64},"idempotency-keys-webhooks-side-effects","Idempotency keys: one webhook, one side effect","Retries are normal. Store the key with the result and enforce it with a unique constraint so a second delivery cannot create a second row.",[54,55,12],"API","Webhooks","\u002Fimages\u002Fjournal\u002Fidempotency-keys-webhooks-side-effects-cover.webp?v=20261013b","Person writing on a printed form","\u002Fimages\u002Fjournal\u002Fidempotency-keys-webhooks-side-effects-hero.webp?v=20261013b","Idempotency Keys for Webhooks | PrimeCode","How an API stores an idempotency key so a retried webhook updates one record instead of creating a second side effect.","\u002Fimages\u002Fjournal\u002Fidempotency-keys-webhooks-side-effects-og.webp?v=20261013b","2026-10-19T01:00:00.000Z",53,"\u002Fblog\u002Fidempotency-keys-webhooks-side-effects",{"slug":66,"title":67,"description":68,"category":8,"readTime":9,"tags":69,"coverImage":71,"coverImageAlt":72,"heroImage":73,"heroImageAlt":72,"metaTitle":74,"metaDescription":75,"ogImage":76,"noindex":20,"published":21,"publishAt":77,"sortOrder":78,"updatedAt":77,"status":24,"path":79},"api-rate-limiting-before-traffic","Rate-limit the API before the expensive routes exist","Login, OTP, search, webhooks, and unbounded page size are the routes to limit first. OWASP API4:2023 is the control, not a new security product.",[54,70,12],"Security","\u002Fimages\u002Fjournal\u002Fapi-rate-limiting-before-traffic-cover.webp?v=20261013b","Padlock resting on a laptop keyboard","\u002Fimages\u002Fjournal\u002Fapi-rate-limiting-before-traffic-hero.webp?v=20261013b","Rate-Limit the API Before Traffic Grows | PrimeCode","Where a Laravel API needs rate limits first — login, OTP, search, and webhooks — and what OWASP API4:2023 actually asks for.","\u002Fimages\u002Fjournal\u002Fapi-rate-limiting-before-traffic-og.webp?v=20261013b","2026-10-16T01:00:00.000Z",52,"\u002Fblog\u002Fapi-rate-limiting-before-traffic"]