WEB / WEB-13.02
Session store ve distributed sessions
Browser aynı session handle’ını taşırken request farklı application node’larına gidebilir. Shared store, güncel binding’i ortaklaştırır; consistency, expiry ve failure kararları yine tasarlanır.
1. Core · Mekanizma
Hareket olmadan bütün senaryoları oku
Güncel binding
- Browser request B’ye zaten ulaştı
Sahne store lookup’tan hemen önce başlar. Handle doğrulama girdisi alınmıştır; credential gösterilmez.
- Browser / Duru
- Request sonucu bekleniyor
- Application Node A
- Idle; bu request’te kullanılmıyor
- Application Node B
- Received request; session unresolved
- Shared session store
- ledger-duru: active v7
- Lookup store’a ulaştı
Node B’nin driver/protocol lookup’ı remote store’a varır. Record hâlâ active v7.
- Browser / Duru
- Request sonucu bekleniyor
- Application Node A
- Idle; bu request’te kullanılmıyor
- Application Node B
- Lookup pending; session unresolved
- Shared session store
- Lookup received; active v7
- Binding yanıtı B’ye ulaştı
Store active v7 binding’ini ve policy alanlarını döndürdü. B bu veriyi değerlendirmeli.
- Browser / Duru
- Request sonucu bekleniyor
- Application Node A
- Idle; bu request’te kullanılmıyor
- Application Node B
- Resolved: active v7; lifetime check pending
- Shared session store
- ledger-duru: active v7
- Session ve resource kararları geçer
Bu branch’te lifetime valid ve ayrı resource authorization supplied allowed’dur. HTTP response hazırlamak artık uygundur.
- Browser / Duru
- Request sonucu bekleniyor
- Application Node A
- Idle; bu request’te kullanılmıyor
- Application Node B
- Session accepted; resource allowed
- Shared session store
- ledger-duru: active v7
- Application response Browser’a ulaştı
Browser request sonucunu öğrenir. Store wire ile HTTP response farklı bağlantılardır.
- Browser / Duru
- Protected request accepted
- Application Node A
- Idle; bu request’te kullanılmıyor
- Application Node B
- Response: 200
- Shared session store
- ledger-duru: active v7
Revoked · eski touch
- A’nın eski snapshot’ı
A daha önce active v7 gördü; B’nin logout’u bu case başlamadan authoritative record’u revoked v8 yaptı.
- Browser / Duru
- A request’i bekleniyor
- Application Node A
- Old snapshot: active v7
- Application Node B
- Earlier logout committed v8
- Shared session store
- Authoritative: revoked v8
- Conditional touch store’a ulaştı
A expected version 7 ile touch ister. Remote receiver’ın current record’u v8 kalır.
- Browser / Duru
- A request’i bekleniyor
- Application Node A
- Touch pending; expected v7
- Application Node B
- Earlier logout committed v8
- Shared session store
- Touch received: expected7/current8; revoked
- Atomic koşul mutation’ı reddeder
Version eşleşmez ve record revoked’dur. Store eski active snapshot’ı yazmaz; v8 değişmez.
- Browser / Duru
- A request’i bekleniyor
- Application Node A
- Touch pending; expected v7
- Application Node B
- Earlier logout committed v8
- Shared session store
- Rejected; revoked v8 unchanged
- Rejection A’ya ulaştı
Authoritative yanıt current revoked v8’i bildirir; A eski snapshot’a dayanamaz.
- Browser / Duru
- A request’i bekleniyor
- Application Node A
- Current resolved: revoked v8; reject session
- Application Node B
- Earlier logout committed v8
- Shared session store
- Rejected; revoked v8 unchanged
- Session reddi Browser’a ulaştı
Fixture HTTP 401 döner; authenticated binding yeniden oluşturulmaz.
- Browser / Duru
- Session invalid; authenticated processing rejected
- Application Node A
- Response: 401
- Application Node B
- Earlier logout committed v8
- Shared session store
- Rejected; revoked v8 unchanged
Lookup error
- Lookup gerekli
Browser request B’dedir. B’nin current binding’i yok; store service bu branch’te erişilemez.
- Browser / Duru
- Request sonucu bekleniyor
- Application Node A
- Idle
- Application Node B
- Session unresolved; lookup required
- Shared session store
- Unreachable; authoritative state not observed
- Lookup failure alındı
Driver error bildirir; completed remote arrival/response yoktur. Wire hareketi uydurulmaz.
- Browser / Duru
- Request sonucu bekleniyor
- Application Node A
- Idle
- Application Node B
- Lookup error; current state unknown
- Shared session store
- Unreachable; authoritative state not observed
- Authenticated processing kabul edilmez
Yeterli trusted state çözülemedi. Error, missing record veya expired session diye yeniden etiketlenmez.
- Browser / Duru
- Request sonucu bekleniyor
- Application Node A
- Idle
- Application Node B
- Fail closed; service failure response prepared
- Shared session store
- Unreachable; authoritative state not observed
- Hizmet hatası Browser’a ulaştı
Fixture HTTP 503 seçer. Browser login state’inin kesin expired olduğunu bu yanıttan çıkaramaz.
- Browser / Duru
- Service unavailable; retry later
- Application Node A
- Idle
- Application Node B
- Response: 503
- Shared session store
- Unreachable; authoritative state not observed
ROLLER · STATE · VERİ AKIŞI
Handle aynı, application node farklı
WEB-13.01’de Browser’ın opaque handle’ı server-side binding’e bağlandı. Şimdi Duru’nun bir request’i Node A’ya, sonraki request’i Node B’ye ulaşsın. İki node’ın aynı handle metnini görmesi, aynı authenticated record’u gördüklerini kendiliğinden kanıtlamaz.
Bu ders opaque server-store session tasarımını ele alır. Record, verified subject, tenant context, lifetime ve revocation state gibi server tarafından yönetilen bilgileri içerir. Browser handle’ı referans taşır; bu record’un authoritative alanlarını client’tan yeniden kurmaz.
Fixture’daki ledger-duru bir audit correlation alias’ıdır; credential değildir. Wire credential ve verifier değeri gösterilmez. Duru/Atlas subject binding’inin önceki güvenli login akışında kurulmuş olduğu bu modelin supplied başlangıç koşuludur.
Process memory neyi sağlar, neyi kaybeder?
Tek application process’i session object’lerini kendi memory’sinde tutabilir. Bu tasarım basittir, fakat başka bir process aynı alanı otomatik paylaşmaz. Process restart olduğunda yalnız volatile memory’de duran record kalıcı disk kaydı gibi geri gelmez.
Bir load balancer’ın sticky session kullanıp Duru’yu Node A’ya yönlendirmesi, node-local tasarımın request’lerini aynı yere götürebilir. Bu routing tercihi ortak session authority yaratmaz. A kaybolursa B’nin elinde record bulunmaması beklenebilir; routing ile state durability aynı sorun değildir.
Tasarımı değerlendirirken “Server session’ı nerede tutuyor?” sorusunu somutlaştır: hangi process veya service owner, hangi lifecycle, hangi loss boundary? “Server-side” demek tek başına restart, scaling veya failover davranışını açıklamaz.
Shared session store: ortak record, ayrı request kararı
Node A ve B ortak bir store üzerinden aynı binding’i çözebilir. Store ayrı bir service olduğunda application↔store mesajı driver/protocol üzerinden gider; Browser↔Application HTTP exchange’iyle aynı bağlantı değildir. Sahne Node B’nin Browser request’ini zaten aldığı noktadan başlar ve remote lookup’ı gösterir.
Başarılı lookup, record’un kullanıma uygun olduğunu tek başına söylemez. Application record’un active/revoked state’ini ve server-side lifetime politikasını kontrol eder; sonra hedef resource için authorization uygular. Session recognition ile resource permission ayrı kararlardır.
Birçok store teknolojisi bu görevi üstlenebilir. “Redis kullandık” veya “database kullandık” demek access isolation, consistency, persistence ve failure policy’nin çözüldüğü anlamına gelmez. Bu ders Redis belgelerini belirli trade-off’ları göstermek için kullanır; her store’a aynı default’u atfetmez.
Stale state: eski active kopya, güncel revoke kararını ezmesin
Fixture’ın başka branch’inde Node A daha önce version 7 active snapshot’ı almıştır. Node B’nin logout akışı shared record’u version 8 revoked durumuna getirmiştir. A’nın eski snapshot’ı bir historical observation’dır; güncel authority değildir.
A eski snapshot üzerinden lastSeen güncellemesi yapıp bütün record’u koşulsuz overwrite ederse revocation’ı kaybedebilir. Savunma için update’i yalnız expected version hâlâ eşleştiğinde, record active olduğunda ve lifetime geçerliyken atomically kabul et. Field update’i de aynı policy sınırını korumalıdır.
Bu fixture’daki conditional touch expected=7 ile current=8’i karşılaştırır, mutation yapmaz ve revoked record’u korur. Version conflict’te son state yeniden okunur ve policy tekrar uygulanır; eski “active” state’i yeniden yazmak için kör retry yapılmaz. Redis’in WATCH/CAS yaklaşımı conditional update için bir örnektir; bu sahne belirli Redis command dizisini çalıştırmaz.
Bir tombstone veya generation/version stratejisinin ne kadar tutulacağı lifecycle tasarımına bağlıdır. Silinmiş session kaydını eski writer’ın yeniden oluşturmasını engellemek de aynı sınırın parçasıdır; missing record üzerinden authenticated upsert yapılmaz.
Consistency ile durability’yi ayrı değerlendir
Shared endpoint kullanmak, bütün reader’ların anında en son state’i gördüğü garantisi değildir. Redis’in temel replication’ı default olarak asynchronous’tur. Replica’dan okuma stratejisi eski state gösterebilir; revocation için kabul edilen consistency boundary’si ayrıca belirlenmelidir.
Redis WAIT, belirtilen sayıda replica’nın acknowledgement bilgisini sağlar; sistemi otomatik strong-consistency sağlayan bir CP sistemine dönüştürmez. Failover sonrasında acknowledged write kaybı ihtimali persistence configuration ile ilişkilidir. Bir acknowledgement ile her türlü crash/failover dayanıklılığını eşitleme.
Persistence için RDB point-in-time snapshot, AOF ise write log ve startup replay yaklaşımı sunar; persistence kapatılabilir de. Bu seçenekler farklı loss ve recovery sınırları taşır. Login veya logout sonucu kullanıcıya başarı olarak bildirilecekse hangi store acknowledgement’ının yeterli olduğu ürünün güvenlik ve availability kararına bağlanır.
Expiry, eviction, missing ve failure aynı sonuç değildir
Session expiry application’ın server-side lifetime kararıdır. Store TTL, artık gerekmeyen record’u temizlemeye yardımcı olabilir; record henüz fiziksel olarak duruyor diye policy deadline geçmiş session kullanılmaz. Expiry enforcement’ı yalnız temizlik zamanına bağlama.
Eviction ise kapasite politikasından doğan veri kaybıdır. Redis eviction policy memory sınırında key’i kaldırabilir. noeviction bunu önlese de yeni veri ekleyen write’lar hata verebilir; sınırsız kapasite veya availability sağlamaz. Session store tek authoritative kopyaysa missing record’u ordinary cache miss gibi client’tan “yeniden üretmek” doğru değildir.
Başarılı lookup’ın “record yok” demesi ile lookup service’inin yanıt verememesi ayrı observation’dır. İlki bu handle için geçerli binding bulunmadığını söyler; ikincisi current state’in bilinmediğini söyler. Bu fixture her ikisinde de authenticated processing’i kabul etmez; service failure’ı expiry gibi etiketlemez.
Duru’nun cookie’sinin hâlâ Browser’da bulunması kaybolan server binding’i geri getirmez. Güvenli yeni authenticated session ancak bağımsız, geçerli authentication akışının sonucu kurulabilir; eski client iddiası missing record’un yerine geçmez.
2. Red · Güven ve etki
Hareket olmadan bütün senaryoları oku
Eski touch
- Node’ın girdisi hazır
Node A’nın historical active snapshot’ı version 7’dir. Güncel store version 8 revoked durumundadır; node bu sonucu henüz yeni lookup ile öğrenmemiştir.
- Application node
- Expected version 7 touch hazır
- Remote session store
- Current version 8 revoked
- Acceptance gate
- Session kararı bekliyor
- Operation remote store’a ulaştı
Node A operation’ı shared authoritative store’a ulaştı. Bu application–store mesajıdır; browser HTTP request’i değildir ve driver protocol ayrıntısı seçilmemiştir.
- Application node
- Store sonucu bekleniyor
- Remote session store
- Expected 7 touch alındı
- Acceptance gate
- Session kararı bekliyor
- Authoritative koşul değerlendirildi
Conditional update expected version 7’yi current version 8 ile karşılaştırır. Ayrıca active ve lifetime koşulları gerekir; revoked kayıt eski active snapshot ile overwrite edilmez.
- Application node
- Store sonucu bekleniyor
- Remote session store
- Version 8 revoked korundu
- Acceptance gate
- Session kararı bekliyor
- Store sonucu hazırlandı
Store conditional-write-rejected sonucunu node’a iletmek üzere hazırlar. Bu aşamada node’ın yeni sonucu aldığını varsaymayız.
- Application node
- Store sonucu bekleniyor
- Remote session store
- Rejected; version 8 unchanged
- Acceptance gate
- Session kararı bekliyor
- Store sonucu node’a ulaştı
Node A version conflict ve revoked state sonucunu aldı. Eski local state güncel authenticated authority gibi kullanılmaz.
- Application node
- Current revoked biliniyor
- Remote session store
- Version 8 unchanged
- Acceptance gate
- Session kararı bekliyor
- Authenticated işlem durduruldu
sessionAccepted=false kalır. Conflict’te trusted state yeniden okunup policy uygulanır; eski snapshot’ı kör retry ile diriltmek gerekçelendirilmez.
- Application node
- Session accepted=false
- Remote session store
- Revoked version 8 unchanged
- Acceptance gate
- Resource işlemi kabul edilmedi
Missing record
- Node’ın girdisi hazır
Node B normal lookup için alias context’ini hazırlar. Browser’da bir handle bulunması, authoritative store’da record bulunduğunu kanıtlamaz.
- Application node
- Lookup hazır; client handle alias
- Remote session store
- Authoritative record missing
- Acceptance gate
- Session kararı bekliyor
- Operation remote store’a ulaştı
Node B operation’ı shared authoritative store’a ulaştı. Bu application–store mesajıdır; browser HTTP request’i değildir ve driver protocol ayrıntısı seçilmemiştir.
- Application node
- Store sonucu bekleniyor
- Remote session store
- Lookup alındı
- Acceptance gate
- Session kararı bekliyor
- Authoritative koşul değerlendirildi
Başarılı lookup record yok sonucunu verir. OnMissing policy, client claim’den yeni authenticated binding oluşturmaz; missing burada transport failure değildir.
- Application node
- Store sonucu bekleniyor
- Remote session store
- Record missing; upsert yok
- Acceptance gate
- Session kararı bekliyor
- Store sonucu hazırlandı
Store success-missing sonucunu node’a iletmek üzere hazırlar. Bu aşamada node’ın yeni sonucu aldığını varsaymayız.
- Application node
- Store sonucu bekleniyor
- Remote session store
- Missing sonucu hazır
- Acceptance gate
- Session kararı bekliyor
- Store sonucu node’a ulaştı
Node B başarılı lookup’ın missing record sonucunu aldı. Eski local state güncel authenticated authority gibi kullanılmaz.
- Application node
- Missing binding biliniyor
- Remote session store
- Record missing
- Acceptance gate
- Session kararı bekliyor
- Authenticated işlem durduruldu
sessionAccepted=false kalır. Yeni session ancak bağımsız geçerli authentication ile kurulabilir; kayıp record cookie metninden yeniden üretilmez.
- Application node
- Session accepted=false
- Remote session store
- Authenticated upsert yok
- Acceptance gate
- Resource işlemi kabul edilmedi
VARSAYIM · SINIR · KONTROL
Sadece happy path node’ını inceleme
Defensive review’da bir session’ın Node A’da tanınmasıyla Node B’de tanınmasını ayrı observation olarak kaydet. Lookup source, observed version ve decision birlikte gerekir. Local cache’in eski active state’i gösterdiği branch, güncel revoke kararının uygulanıp uygulanmadığını anlamaya yarar.
Logout response’u ile bütün okuyucuların revocation’ı görmesi arasındaki boundary’yi sor. Network ve replica davranışı tasarımın parçasıdır. Her stale record anında bir compromise değildir; güvenlik etkisi application’ın o kaydı hangi kararda kabul ettiğine bağlıdır.
Store erişimi de credential sınırıdır
Session store yalnız “performans cache’i” olarak etiketlenip geniş erişime açılmamalıdır. Raw random token saklayan bir store’u okuyabilen taraf, hâlâ geçerli credential elde edebilir. High entropy disclosure’ı önlemez.
OWASP, read-only store disclosure threat model’inde one-way verifier saklamayı değerlendirir. Bu koruma read-only disclosure’a yöneliktir; record modification veya application compromise’ı çözmez. Bu derste hiçbir raw token ya da verifier bulunmaz; ledger alias’ı authentication proof gibi kullanılamaz.
3. Blue · Güvenli geliştirme ve savunma
Hareket olmadan bütün senaryoları oku
Policy expiry
- Session decision satırı seçildi
Bu inceleme policy-expired satırını ele alır. İki branch’te de sessionAccepted=false olmasına rağmen trusted state hakkındaki kanıtları aynı değildir.
- Decision kaydı
- case=policy-expired
- Lookup incelemesi
- Lookup incelenmedi
- Evidence hükmü
- Neden belirlenmedi
- Lookup kaynağı ayrıldı
Lookup success ve source=authoritative’tir; observedVersion=7 bilinir. Physical record active görünürken application lifetime policy ayrıca değerlendirilir.
- Decision kaydı
- case=policy-expired
- Lookup incelemesi
- Success; authoritative; version 7
- Evidence hükmü
- Neden belirlenmedi
- Lifetime kanıtı değerlendirildi
lifetimeValid=false policy expiry sonucunu açıklar. Record’un fiziksel olarak durması geçerli session authority’yi sürdürmez; TTL cleanup ayrı mekanizmadır.
- Decision kaydı
- case=policy-expired
- Lookup incelemesi
- Lifetime invalid; record present
- Evidence hükmü
- Expiry biliniyor
- Fail-closed kararı sınırlandı
Artifact authenticated processing’i kabul etmez. Bu karar bilinen expiry’ye dayanır; iki reason tek logout/expiry etiketi altında birleştirilmez.
- Decision kaydı
- case=policy-expired
- Lookup incelemesi
- sessionAccepted=false
- Evidence hükmü
- Known expiry
- Selector sonucu kapsamıyla okundu
Ana selector accepted=true olup known/active/lifetime koşulu eksik satırları arar ve 0 verir. Ayrı positive fixture 1 verir; bu kayıtlar gerçek Redis metric veya latency ölçümü değildir.
- Decision kaydı
- case=policy-expired
- Lookup incelemesi
- Integrity count=0; positive=1
- Evidence hükmü
- Reason ayrı korunuyor
- Recovery iddiası eklenmedi
Bu satır session policy expiry’yi açıklar; eviction, crash veya replication nedenleri bu sonuçtan türetilmez.
- Decision kaydı
- case=policy-expired
- Lookup incelemesi
- Authenticated acceptance yok
- Evidence hükmü
- Policy expiry biliniyor
Store error
- Session decision satırı seçildi
Bu inceleme store-unavailable satırını ele alır. İki branch’te de sessionAccepted=false olmasına rağmen trusted state hakkındaki kanıtları aynı değildir.
- Decision kaydı
- case=store-unavailable
- Lookup incelemesi
- Lookup incelenmedi
- Evidence hükmü
- Neden belirlenmedi
- Lookup kaynağı ayrıldı
Lookup error ve source=unknown’dur; observedVersion=null kalır. Application current record state’ini öğrenememiştir.
- Decision kaydı
- case=store-unavailable
- Lookup incelemesi
- Error; unknown source/version
- Evidence hükmü
- Neden belirlenmedi
- Lifetime kanıtı değerlendirildi
Store yanıt veremediği için lifetime veya revoked state sonucu çıkarılmaz. Service unavailable product sonucu expiry’nin gözlendiği anlamına gelmez.
- Decision kaydı
- case=store-unavailable
- Lookup incelemesi
- Current lifecycle bilinmiyor
- Evidence hükmü
- UNKNOWN: lifecycle
- Fail-closed kararı sınırlandı
Artifact authenticated processing’i kabul etmez. Bu karar trusted state çözülememesine dayanır; iki reason tek logout/expiry etiketi altında birleştirilmez.
- Decision kaydı
- case=store-unavailable
- Lookup incelemesi
- sessionAccepted=false
- Evidence hükmü
- UNKNOWN: record state
- Selector sonucu kapsamıyla okundu
Ana selector accepted=true olup known/active/lifetime koşulu eksik satırları arar ve 0 verir. Ayrı positive fixture 1 verir; bu kayıtlar gerçek Redis metric veya latency ölçümü değildir.
- Decision kaydı
- case=store-unavailable
- Lookup incelemesi
- Integrity count=0; positive=1
- Evidence hükmü
- Reason ayrı korunuyor
- Recovery iddiası eklenmedi
Bu satır service error’ı açıklar; session record’un silindiğini veya expired olduğunu kanıtlamaz. Recovery için trusted store state’i tekrar çözülmelidir.
- Decision kaydı
- case=store-unavailable
- Lookup incelemesi
- Authenticated acceptance yok
- Evidence hükmü
- UNKNOWN: current store state
UYGULAMA · GÜVENLİK KONTROLÜ · DOĞRULAMA
Authoritative state ve read policy’yi belirle
Her node için aynı binding kaynağını, revocation visibility beklentisini ve approved read path’i tanımla. Replica veya local cache kullanılıyorsa stale state’in hangi kararlar için kabul edilebildiğini açıkça sınırla; yalnız kısa cache TTL söylemek güçlü consistency garantisi değildir.
Store erişimini gerekli application bileşenleriyle sınırla, transport ve at-rest/backup korumalarını uygula. Credential’ların gözlem sistemlerine sızmaması için opaque audit correlation kullan. Persistence ve failover policy’sini session lifecycle beklentisiyle birlikte değerlendir.
Lifetime update’ini atomic policy yap
Touch/refresh için expected version, active state ve lifetime koşulunu aynı atomik boundary’de değerlendir. Conflict’te yeniden oku; revoked/missing/expired state’i valid authentication olmadan active’a çevirmeyi reddet. Generic upsert bu policy’nin yerini tutmaz.
Conditional primitive’lerin hata semantiğini backend belgesinden doğrula. IndexedDB transaction abort’unun bütün değişiklikleri geri alması, Redis transaction’ın execution-time hatalarda rollback yaptığı anlamına gelmez; Redis bu tür rollback sağlamaz. “Transaction” adını bütün teknolojiler için aynı garanti sanma.
Failure’ı güvenli ve anlaşılır göster
Record missing, policy expired, capacity eviction ve service unavailable observation’larını ayır. Authenticated processing için yeterli trusted state çözülemiyorsa bu fixture fail closed davranır; kullanıcıya hizmet hatasını logout kanıtı diye sunmaz. Retry ve recovery authenticated authority uyduramaz.
Capacity takibinde eviction, expiry ve write rejection göstergelerini farklı izle. Bu dersin defteri ölçülmüş latency, throughput veya gerçek Redis metric sonucu vermez; yalnız kendi deterministic branch’lerinin karar gerekçesini gösterir.
ŞİMDİ VAKAYA UYGULA
Eski snapshot ve store failure hangi kararı değiştiremez?
Node’lar ortak authoritative binding’i kullanır. Conditional touch güncel revoke kararını korur; bilinmeyen lookup state’i expiry diye sunulmaz.
Vakadaki handle, server binding ve session lifetime için ayrı observation ara. Browser’da kalan değer server’ın güncel kabul kararını tek başına anlatır mı?
Bağlı vaka dosyasını aç ↗ÖRNEĞİ BİRLİKTE OKUYALIM
İki node ve authoritative session defteri
Bir alan seç; hangi sonucu desteklediğini ve nerede yetersiz kaldığını incele.
Ham kaydı ve alan açıklamalarını oku
{
"architecture": "opaque handle + remote authoritative session store; driver protocol unspecified",
"auditCorrelation": "ledger-duru; not a credential",
"subject": {
"displayName": "Duru",
"tenant": "Atlas",
"binding": "supplied previously verified authentication; wire token omitted"
},
"cases": [
{
"case": "normal",
"node": "B",
"lookup": "success",
"source": "authoritative",
"observedVersion": 7,
"recordState": "active",
"lifetimeValid": true,
"sessionAccepted": true,
"resourceAuthorization": "separate required decision"
},
{
"case": "stale-touch",
"node": "A",
"lookup": "conditional-write-rejected",
"source": "authoritative",
"expectedVersion": 7,
"observedVersion": 8,
"recordState": "revoked",
"recordAfter": "revoked version 8 unchanged",
"sessionAccepted": false
},
{
"case": "missing-after-eviction",
"node": "B",
"lookup": "success-missing",
"source": "authoritative",
"observedVersion": null,
"recordState": "missing",
"capacityObservation": "authored eviction branch; not a measured Redis event",
"sessionAccepted": false
},
{
"case": "policy-expired",
"node": "B",
"lookup": "success",
"source": "authoritative",
"observedVersion": 7,
"recordState": "active physical record",
"lifetimeValid": false,
"sessionAccepted": false
},
{
"case": "store-unavailable",
"node": "B",
"lookup": "error",
"source": "unknown",
"observedVersion": null,
"recordState": "unknown to application",
"sessionAccepted": false,
"productOutcome": "service unavailable; not proof of expiry"
}
],
"conditionalUpdatePolicy": {
"required": [
"record exists",
"expected version matches",
"record active",
"lifetime valid"
],
"onConflict": "reread trusted state and reapply policy; no blind resurrection",
"onMissing": "do not create authenticated binding from client claim"
},
"selector": {
"xml": "<sessions><decision case=\"normal\" accepted=\"true\" known=\"true\" active=\"true\" lifetime=\"true\"/><decision case=\"stale-touch\" accepted=\"false\" known=\"true\" active=\"false\" lifetime=\"true\"/><decision case=\"missing-after-eviction\" accepted=\"false\" known=\"false\" active=\"false\" lifetime=\"false\"/><decision case=\"policy-expired\" accepted=\"false\" known=\"true\" active=\"true\" lifetime=\"false\"/><decision case=\"store-unavailable\" accepted=\"false\" known=\"false\" active=\"false\" lifetime=\"false\"/></sessions>",
"xpath": "count(/sessions/decision[@accepted=\"true\" and (@known!=\"true\" or @active!=\"true\" or @lifetime!=\"true\")])",
"expected": 0,
"positiveFixtureXml": "<sessions><decision accepted=\"true\" known=\"false\" active=\"false\" lifetime=\"false\"/></sessions>",
"positiveExpected": 1
}
}- lookup / source
- Lookup sonucu ve freshness kaynağı; error, missing ve eski snapshot birbirinden ayrıdır.
- expectedVersion / observedVersion
- Conditional update’in concurrency koşulu; güvenlik credential’ı değildir.
- recordState / lifetimeValid
- Fiziksel record varlığı active ve lifetime uygunluğu yerine geçmez.
- sessionAccepted
- Bu fixture’ın session decision’ı; resource authorization sonucu değildir.
- selector
- Accepted için known+active+lifetime invariant’ını sorgular; gerçek telemetry değildir.
Remote store tek logical authority olarak varsayılır; replica/failover etkileri açıklanır ama bu sahnede simüle edilmez. Version 7/8 alias’tır; latency ve TTL sayısı verilmez. HTTP 401/503 bu fixture’ın seçilmiş response’larıdır. Gerçek store, credential veya load balancer çalıştırılmadı.
İki yanlış kanı
Shared session store bütün node’lara anında aynı güncel state’i ve kayıpsız failover’ı garanti eder.
Read path, replication consistency ve persistence ayrı tasarım kararlarıdır. Redis default async replication kullanır; WAIT tek başına strong consistency veya her failover’a karşı durability garantisi vermez.
Store’da record yoksa cookie’den yeniden authenticated session kurulur; store error da expiry demektir.
Missing binding client iddiasıyla yeniden authenticated hale getirilemez. Lookup error current state’i unknown bırakır; expiry application’ın lifetime kararıdır. Bu fixture yeterli trusted state yoksa authenticated processing’i reddeder.
SIRA SENDE
Bu hikâyeyi sen çöz.
Sonucu tahmin et, kanıtın sınırını bul ve nedenini kendi cümlenle anlat.
NodeA expectedVersion=7 ile touch yapıyor. Authoritative record version=8 ve revoked. Write sonucu ne olur?
- Version=7 snapshot’ı revoked state’i yeniden active yapar.
- Reddedilir. Revoked version=8 değişmez.
Gerekçeli cevabı oku
Reddedilir. Revoked version=8 değişmez. — Eski touch, revoked binding’i yeniden açamaz. Conflict sonrasında güncel güvenilen state’in yeniden okunması gerekir.
Store lookup hatası, session’ın expired olduğunu kanıtlar mı?
Dersten seçilen artifact alanları; öğretim örneği
- cases[4]
- {"case":"store-unavailable","node":"B","lookup":"error","source":"unknown","observedVersion":null,"recordState":"unknown to application","sessionAccepted":false,"productOutcome":"service unavailable; not proof of expiry"}
- Hayır. Record bilinmiyor; kabul durur ve service unavailable olur.
- Evet. Her store hatasının nedeni session expiry’dir.
Gerekçeli cevabı oku
Hayır. Record bilinmiyor; kabul durur ve service unavailable olur. — Bu sonuç expiry kanıtı değildir. Missing ve expired branch’leri ayrı gözlemler sağlar; burada record state’i bilinmiyor.
Eviction sonrasında success-missing ile fiziksel olarak bulunan fakat lifetime-invalid record neden farklıdır? İkisinde de accepted=false.
Gerekçeli cevabı oku
Başarılı missing lookup binding bulamaz; client iddiasından yeniden oluşturulmaz. Süresi dolmuş record ise fiziksel olarak durabilir ama lifetime kontrolünden geçmez. Eviction, durability ve replication mekanizmaları login policy’sinin yerine geçmez. Shared store’un session’ı kabul etmesi de resource izni değildir.
□ Fiziksel yokluk ile logical expiry’yi ayırdım.
□ Store mekanizmalarını authentication policy’sinin yerine koymadım.
Uygulama konsolunu aç · request / response / browser
Request, URL, cookie ve DOM örneklerini ayrıca aç
Kaynaklar ve kapsam
- OWASP — Session Management Cheat SheetSession ID Content (or Value) · Built-in Session Management Implementations · Server-Side Session Token Storage · Session Expiration · Logging Sessions Life Cycle
- OWASP — Authorization Cheat SheetValidate the Permissions on Every Request · Verify that Authorization Checks are Performed in the Right Location
- Redis — Key evictionUsing the maxmemory configuration directive · Eviction policies: noeviction · Using the INFO command: evicted_keys versus expired_keys
- Redis — ReplicationRedis replication: asynchronous default and WAIT limitations
- Redis — PersistencePersistence options: RDB, AOF, no persistence · RDB disadvantages
- Redis — TransactionsOptimistic locking using check-and-set · WATCH explained · Errors inside a transaction · What about rollbacks?