c73ba6a964
Demo idzie szeroko i do różnych osób, często na cudzych komputerach — więc
wyjście z aplikacji jest tu potrzebne bardziej niż w pełnej wersji, a Basic go
nie miał: przeglądarka zapamiętuje hasło i dosyła je sama przy każdym żądaniu.
Pierwszy klient zostawiał otwartą sesję drugiemu.
Ta sama konstrukcja co w pełnej aplikacji: własny ekran logowania, podpisane
ciasteczko (HMAC-SHA256), HttpOnly + SameSite=Strict, wylogowanie POST-em, kres
bezczynności i twardy, sito na adres powrotu, zdarzenia w dzienniku bez haseł.
Moduł session.py skopiowany, tak samo jak link_crypto — usługi są osobnymi
obrazami i nie importują się nawzajem.
DWIE RÓŻNICE WOBEC PEŁNEJ WERSJI, obie wynikające z tego, że demo nie ma
własnego wolumenu:
* nazwa ciasteczka jest inna. Gdyby obie aplikacje stanęły kiedyś pod jedną
domeną, ciasteczka o tej samej nazwie nadpisywałyby się i człowiek wypadałby
z jednej, logując się do drugiej.
* nie ma licznika pokolenia sesji, bo nie ma go gdzie zapisać. Zdalne
unieważnienie robi się przez DEMO_USERS: usunięcie konta albo zmiana hasła
NATYCHMIAST ubija jego otwarte sesje, bo odcisk poświadczenia w ciasteczku
przestaje pasować. Osobny test tego pilnuje. Wylogowanie i tak działa
natychmiast, bo polega na skasowaniu ciasteczka.
Klucz podpisu jest WŁASNY, nie ten z pełnej aplikacji: demo i produkcja nie mają
powodu uznawać nawzajem swoich sesji, a wspólny klucz znaczyłby, że sesja z demo
bywa ważna tam, gdzie nie powinna.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
37 lines
1.3 KiB
HTML
37 lines
1.3 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="pl">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>astroklient-demo · logowanie</title>
|
|
<link rel="stylesheet" href="/static/styles.css">
|
|
</head>
|
|
<body>
|
|
<main class="login-main">
|
|
<header class="topbar"><h1>astroklient-demo</h1></header>
|
|
|
|
{% if request.query_params.get('wylogowano') %}
|
|
<p class="ok">Wylogowano.</p>
|
|
{% endif %}
|
|
{% if blad %}<p class="alert">{{ blad }}</p>{% endif %}
|
|
|
|
<form method="post" action="/logowanie" class="card login-card">
|
|
{# Adres powrotu jedzie w ukrytym polu, ale i tak przechodzi przez sito
|
|
po stronie serwera — pole formularza jest wejściem od użytkownika. #}
|
|
<input type="hidden" name="dokad" value="{{ dokad }}">
|
|
<label>Login
|
|
<input type="text" name="login" value="{{ login or '' }}" required
|
|
autocomplete="username" autofocus></label>
|
|
<label>Hasło
|
|
<input type="password" name="haslo" required autocomplete="current-password"></label>
|
|
<div class="actions"><button type="submit">Zaloguj</button></div>
|
|
</form>
|
|
|
|
<p class="muted small login-note">
|
|
Nie masz konta albo nie pamiętasz hasła? Zgłoś się do osoby, która zakładała
|
|
Ci dostęp — kont nie da się odzyskać samodzielnie.
|
|
</p>
|
|
</main>
|
|
</body>
|
|
</html>
|