app.use(session({
store: new RedisStore({ client: redisClient, ttl: 86400 }), // TTL în secunde pe server (24h)
secret: 'my-super-secret',
resave: false,
saveUninitialized: false,
rolling: true, // <- IMPORTANT: resetează maxAge la fiecare request
cookie: {
secure: true,
maxAge: 30 * 24 * 60 * 60 * 1000 // 30 de zile în browser
}
}));Am pățit-o acum vreo doi ani pe un proiect cu 14.000 de useri activi pe zi. Ne-au asaltat tichetele de suport: oamenii erau delogați din senin după câteva minute de inactivitate, deși în browser cookie-ul de sesiune arăta clar că expiră peste o lună.
Dacă ești în situația asta, respiră adânc. Nu ești nebun și nici browserul nu are personalitate multiplă. Problema nu e la client, ci aproape sigur în spatele scenei, unde se bat cap în cap expirarea cookie-ului și expirarea sesiunii de pe server.
Serverul uită înaintea browserului
Cea mai comună greșeală este confuzia dintre durata de viață a cookie-ului (pe client) și durata de viață a sesiunii (pe server). Tu poți să-i spui browserului maxAge: 30 * 24 * 60 * 60 * 1000 (adică 30 de zile), dar dacă serverul tău își curăță memoria RAM la fiecare 5 minute, cookie-ul ăla devine o cheie inutilă către o cameră care nu mai există.
Dacă folosești PHP, Node.js cu Express-session sau .NET, verifică unde sunt stocate sesiunile. Implicit, multe framework-uri le țin în memorie (in-memory store). La un restart de proces (care în cloud se poate întâmpla des din cauza auto-scaling-ului sau a unui health check prost configurat), toată lumea e delogată instant.
Redis și capcana lui "idle timeout"
La proiectul de care ziceam, noi foloseam Redis ca session store. Teoretic, stabil și sigur. Practic, uitasem de setarea de timeout din Redis și de configurația din Express.
Dacă folosești Redis, verifică setarea timeout din redis.conf. Dacă e setată pe 300 (secunde), Redis va închide conexiunile inactive după 5 minute.
De asemenea, în codul tău de backend, asigură-te că ai activat opțiunea de rolling sessions. Fără rolling: true, sesiunea expiră la X minute de la creare, indiferent dacă userul a fost activ în tot acest timp sau nu. Practic, dacă userul citește un articol lung timp de 5 minute, la următorul click e delogat.
Load balancer-ul care taie conexiuni
Dacă totul pare corect în cod și în baza de date, ridică privirea spre infrastructură. Am pierdut o zi întreagă pe un proiect AWS pentru că un Application Load Balancer (ALB) avea un Idle timeout setat pe 300 de secunde (fix 5 minute).
Sesiunile noastre foloseau server-sent events (SSE) sau conexiuni lungi de HTTP, iar AWS pur și simplu le tăia nodul dacă nu trecea trafic prin ele timp de 5 minute. Clientul primea un 504 sau conexiunea murea silențios, iar aplicația de React, văzând eroarea, făcea fallback pe delogare automată.
Trade-off-ul pe care trebuie să-l accepți
Poți rezolva asta rapid mărind session timeout-ul pe server la 30 de zile, dar ai grijă la costuri. Dacă ai peste 10k useri și le ții sesiunile active în Redis timp de o lună fără curățare, memoria o să te coste de o să-ți sară capacele.
Sfatul meu: ține sesiunea pe server la maximum 2-3 ore de inactivitate, folosește rolling: true ca să prelungiești sesiunea doar dacă userul e activ, și implementează un mecanism separat de "remember me" cu un refresh token securizat stocat în baza de date pentru perioade mai lungi.
Voi cum ați rezolvat buba asta ultima oară? A fost din config-ul de server sau v-a bătut infrastructura?