Přeskočit na obsah

Vlastní getUser() v API route závodí s refreshem session v middleware

import { Aside } from ‘@astrojs/starlight/components’;

Na dlouho otevřené (admin) stránce občas akce přes fetch (odeslat zprávu, uložit) spadne na červené „Authentication required”, i když je uživatel přihlášený. Po reloadu stránky to chvíli funguje, pak zas ne. Opakující se, těžko reprodukovatelné.

Middleware správně obnovuje session a plní locals.user:

let { data: { user } } = await supabase.auth.getUser();
if (!user && refreshTokenCookie) {
const { data } = await supabase.auth.refreshSession();
// zapíše nové cookies, nastaví locals.user
}

Ale API endpoint si dělal vlastní ověření:

// ŠPATNĚ — druhá, nezávislá validace
const { data: { user }, error } = await supabase.auth.getUser();
if (error || !user) return 401;

getUser() re-validuje access token. Když vypršel (JWT ~1 h), pokusí se o refresh — ale refresh tokeny rotují (jsou single-use). Middleware už refresh provedl a token spotřeboval; endpointova druhá validace pak selže → 401. Na čerstvě načtené stránce token platí, takže to „někdy funguje”.

Endpoint čte uživatele z locals (vyřešeno middlewarem), ne vlastním getUser:

export const POST = async ({ request, locals }) => {
const user = locals.user; // vyřešeno + refreshnuto middlewarem
if (!user) return 401;
const role = locals.profile?.role; // taktéž z middleware
// ...
};

Jak se tomu vyvarovat v jiných systémech

Sekce “Jak se tomu vyvarovat v jiných systémech”
  • Detection: grep getUser() / getSession() v API endpointech. Pokud middleware už řeší session, je to duplicitní + race-prone.
  • Anti-pattern: dvě nezávislá místa validující/refreshující stejný token; re-validace tokenu na write cestě.
  • Lepší přístup: (1) jeden zdroj pravdy pro auth (middleware → locals/context); (2) refresh tokeny rotují → nikdy je nevaliduj paralelně dvakrát; (3) test: nech stránku „vyčkat” přes expiraci access tokenu a spusť fetch akci.

Sister bugs / související

Sekce “Sister bugs / související”
Přidal aiarchitekt.cz · 26. 5. 2026 2:00
Provozuje aiarchitekt.cz