Przycisk wylogowania (LOG-32) #75

Merged
gitea merged 1 commits from fix/wylogowanie into master 2026-08-20 21:53:51 +00:00
Owner

Aplikacja nie miała jak z siebie wyjść: raz podane hasło działało do zamknięcia przeglądarki, a na wspólnym komputerze nie było sposobu, żeby oddać ekran komuś innemu.

Rzecz, którą trzeba powiedzieć wprost

HTTP Basic nie ma prawdziwego wylogowania. Nie ma sesji do skasowania: przeglądarka zapamiętuje login i hasło, po czym dosyła je sama przy każdym żądaniu. Serwer nie ma czego zapomnieć — kolejne kliknięcie przyszłoby z kompletem poświadczeń i weszłoby z powrotem.

Działa natomiast doprowadzenie do tego, żeby to przeglądarka porzuciła zapamiętane dane. Robimy to dwutorowo, bo żadne z osobna nie wystarcza:

co daje czego nie daje
/wyloguj zawsze zwraca 401 z WWW-Authenticate wymusza ponowne pytanie o hasło, działa bez JavaScriptu zostawia stare dane w pamięci — po anulowaniu okienka wystarczy wejść na dowolny adres, żeby wrócić
wyloguj.js wysyła żądanie z celowo błędnymi danymi przeglądarka nadpisuje nim swój wpis — to ta część faktycznie czyści pamięć opiera się na zachowaniu powszechnym, ale nie zapisanym w standardzie

Strona wylogowania mówi wprost, że pewnym sposobem w każdej przeglądarce jest zamknięcie okna. Nie obiecuję więcej, niż Basic potrafi: obietnica bez pokrycia byłaby tu gorsza od braku przycisku, bo dawałaby złudzenie, że ekran jest oddany.

Szczegóły, które nie są przypadkowe

  • trasa stoi poza bramką logowania — inaczej dostałaby 200 od zalogowanej sesji i nie miałaby jak odpowiedzieć 401
  • odpowiada też bez logowania — inaczej wyjście wymagałoby bycia w środku, co jest błędnym kołem
  • zakaz zapamiętywania strony — oddana z pamięci podręcznej nie dotarłaby do serwera i okienko w ogóle by się nie pojawiło
  • obok wyjścia widać, kto jest zalogowany: bez tego przycisk jest w połowie bezużyteczny, bo na wspólnym komputerze nie wiadomo, kogo się wylogowuje
  • przy wyłączonym logowaniu nie ma ani jednego, ani drugiego — przycisk sugerowałby ochronę, której nie ma

Weryfikacja

8 nowych testów; prezentacja 311 zielonych.

Sprawdzone w przeglądarce: oba żądania wychodzą (to z błędnymi danymi i samo przejście), oba wracają 401, strona renderuje się poprawnie, przycisk stoi na końcu paska oddzielony od zakładek.

Czego nie dało się tu potwierdzić: samego unieważnienia pamięci poświadczeń — wymaga okienka systemowego, którego automat nie obsłuży. To jest ta część opierająca się na zachowaniu przeglądarki, więc warto sprawdzić ją ręcznie po wdrożeniu.

🤖 Generated with Claude Code

Aplikacja nie miała jak z siebie wyjść: raz podane hasło działało do zamknięcia przeglądarki, a na wspólnym komputerze nie było sposobu, żeby oddać ekran komuś innemu. ## Rzecz, którą trzeba powiedzieć wprost **HTTP Basic nie ma prawdziwego wylogowania.** Nie ma sesji do skasowania: przeglądarka zapamiętuje login i hasło, po czym **dosyła je sama** przy każdym żądaniu. Serwer nie ma czego zapomnieć — kolejne kliknięcie przyszłoby z kompletem poświadczeń i weszłoby z powrotem. Działa natomiast doprowadzenie do tego, żeby to **przeglądarka** porzuciła zapamiętane dane. Robimy to dwutorowo, bo żadne z osobna nie wystarcza: | | co daje | czego nie daje | |---|---|---| | `/wyloguj` zawsze zwraca **401** z `WWW-Authenticate` | wymusza ponowne pytanie o hasło, działa **bez JavaScriptu** | zostawia stare dane w pamięci — po anulowaniu okienka wystarczy wejść na dowolny adres, żeby wrócić | | `wyloguj.js` wysyła żądanie z **celowo błędnymi** danymi | przeglądarka nadpisuje nim swój wpis — to **ta część faktycznie czyści pamięć** | opiera się na zachowaniu powszechnym, ale **nie zapisanym w standardzie** | Strona wylogowania mówi wprost, że pewnym sposobem w **każdej** przeglądarce jest zamknięcie okna. Nie obiecuję więcej, niż Basic potrafi: obietnica bez pokrycia byłaby tu **gorsza od braku przycisku**, bo dawałaby złudzenie, że ekran jest oddany. ## Szczegóły, które nie są przypadkowe - trasa stoi **poza bramką logowania** — inaczej dostałaby 200 od zalogowanej sesji i nie miałaby jak odpowiedzieć 401 - odpowiada **też bez logowania** — inaczej wyjście wymagałoby bycia w środku, co jest błędnym kołem - **zakaz zapamiętywania strony** — oddana z pamięci podręcznej nie dotarłaby do serwera i okienko w ogóle by się nie pojawiło - obok wyjścia widać, **kto jest zalogowany**: bez tego przycisk jest w połowie bezużyteczny, bo na wspólnym komputerze nie wiadomo, kogo się wylogowuje - przy **wyłączonym logowaniu** nie ma ani jednego, ani drugiego — przycisk sugerowałby ochronę, której nie ma ## Weryfikacja 8 nowych testów; prezentacja **311 zielonych**. Sprawdzone w przeglądarce: oba żądania wychodzą (to z błędnymi danymi i samo przejście), oba wracają 401, strona renderuje się poprawnie, przycisk stoi na końcu paska oddzielony od zakładek. **Czego nie dało się tu potwierdzić:** samego unieważnienia pamięci poświadczeń — wymaga okienka systemowego, którego automat nie obsłuży. To jest ta część opierająca się na zachowaniu przeglądarki, więc warto sprawdzić ją ręcznie po wdrożeniu. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
gitea added 1 commit 2026-08-20 21:52:29 +00:00
feat(bezpieczeństwo): przycisk wylogowania (LOG-32)
Testy / Testy warstwy logicznej (silnik) (pull_request) Successful in 10m17s
Testy / Testy warstwy prezentacji (dostęp do baz) (pull_request) Successful in 9m29s
Testy / Testy warstwy bazodanowej (ochrona baz) (pull_request) Successful in 9m25s
Testy / Build obrazu silnika B (swisseph) (pull_request) Successful in 5s
Testy / Kontrola składni wszystkich warstw (pull_request) Successful in 4s
build / build (push) Successful in 1m18s
Testy / Testy warstwy logicznej (silnik) (push) Successful in 10m21s
Testy / Testy warstwy prezentacji (dostęp do baz) (push) Successful in 9m29s
Testy / Testy warstwy bazodanowej (ochrona baz) (push) Successful in 9m25s
Testy / Build obrazu silnika B (swisseph) (push) Successful in 5s
Testy / Kontrola składni wszystkich warstw (push) Successful in 4s
71bb3b9c0a
Aplikacja nie miała jak z siebie wyjść: raz podane hasło działało do zamknięcia
przeglądarki, a na wspólnym komputerze nie było sposobu, żeby oddać ekran komuś
innemu.

HTTP BASIC NIE MA PRAWDZIWEGO WYLOGOWANIA i to jest sedno tej zmiany. Nie ma
sesji do skasowania: przeglądarka zapamiętuje login i hasło, po czym dosyła je
SAMA przy każdym żądaniu. Serwer nie ma czego zapomnieć — kolejne kliknięcie
przyszłoby z kompletem poświadczeń i weszłoby z powrotem.

Działa natomiast doprowadzenie do tego, żeby to PRZEGLĄDARKA porzuciła zapamiętane
dane, i robimy to dwutorowo, bo ani jedno, ani drugie osobno nie wystarcza:

  1. /wyloguj odpowiada ZAWSZE 401 z nagłówkiem WWW-Authenticate, co wymusza
     ponowne pytanie o hasło. Działa bez JavaScriptu, ale samo w sobie zostawia
     stare dane w pamięci przeglądarki: po anulowaniu okienka wystarczyłoby wejść
     na dowolny adres, żeby wrócić do środka.
  2. wyloguj.js wysyła żądanie z CELOWO błędnymi danymi, którym przeglądarka
     nadpisuje swój wpis. To jest część, która faktycznie czyści pamięć — ale
     opiera się na zachowaniu powszechnym, a nie zapisanym w standardzie, więc
     nie może być jedynym mechanizmem.

Strona wylogowania mówi wprost, że pewnym sposobem w KAŻDEJ przeglądarce jest
zamknięcie okna. Nie obiecujemy więcej, niż Basic potrafi — obietnica bez pokrycia
byłaby tu gorsza od braku przycisku, bo dawałaby złudzenie, że ekran jest oddany.

Trasa stoi POZA bramką logowania, celowo: inaczej dostałaby 200 od zalogowanej
sesji i nie miałaby jak odpowiedzieć 401. Odpowiada też bez logowania — inaczej
wyjście wymagałoby bycia w środku, co jest błędnym kołem. Nagłówki zakazują
zapamiętania strony, bo oddana z pamięci podręcznej nie dotarłaby do serwera
i okienko w ogóle by się nie pojawiło.

Obok wyjścia pokazujemy, KTO jest zalogowany: bez tego przycisk jest w połowie
bezużyteczny, bo na wspólnym komputerze nie wiadomo, kogo się wylogowuje. Przy
wyłączonym logowaniu nie ma ani jednego, ani drugiego — przycisk sugerowałby
ochronę, której nie ma.

Sprawdzone w przeglądarce: oba żądania wychodzą (to z błędnymi danymi i samo
przejście), oba wracają 401, strona renderuje się poprawnie. Samego unieważnienia
pamięci poświadczeń NIE dało się tu potwierdzić — wymaga okienka systemowego,
którego automat nie obsłuży.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gitea merged commit 71bb3b9c0a into master 2026-08-20 21:53:51 +00:00
gitea deleted branch fix/wylogowanie 2026-08-20 21:53:51 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: gitea/astrololo#75