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>
31 lines
1.1 KiB
HTML
31 lines
1.1 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 · {% block title %}{% endblock %}</title>
|
|
<link rel="stylesheet" href="/static/styles.css">
|
|
</head>
|
|
<body>
|
|
<main>
|
|
<header class="topbar">
|
|
<h1>astroklient-demo</h1>
|
|
{# Kto jest zalogowany i wyjście. Demo bywa używane na cudzych komputerach,
|
|
więc bez tego pierwszy klient zostawia otwartą sesję drugiemu. #}
|
|
{% if auth_on() %}
|
|
<div class="kto">
|
|
<span class="whoami">{{ current_user(request) }}</span>
|
|
<form method="post" action="/wyloguj" class="wyloguj-form">
|
|
<button type="submit" class="wyloguj">Wyloguj</button>
|
|
</form>
|
|
</div>
|
|
{% endif %}
|
|
{# CELOWO BEZ NAWIGACJI. Dwie funkcje mieszczą się na jednym ekranie,
|
|
a pasek zakładek z jedną pozycją tylko sugerowałby, że są inne. #}
|
|
</header>
|
|
{% block content %}{% endblock %}
|
|
<footer class="foot">wersja demonstracyjna</footer>
|
|
</main>
|
|
</body>
|
|
</html>
|