Authentik auth

This commit is contained in:
Local User
2026-05-01 19:37:40 +03:00
parent 51495deece
commit 3a8514d435
4 changed files with 480 additions and 331 deletions

122
README.md
View File

@@ -1,42 +1,40 @@
# Million Miles Auth
# Million Miles Authentik POC
Локальный POC с `Authentik` и кастомным frontend:
POC с кастомными формами `login/register`, где `Authentik` используется только как backend IdP.
- регистрация пользователя на своей форме
- вход пользователя на своей форме
- Authentik используется как backend авторизации
- после входа frontend показывает данные из `id_token`
## Что реализовано
## Что в проекте
- `/login` — кастомная форма `Email / Password / Войти`
- `/register` — кастомная форма `Full name / Email / Password / Confirm password`
- `Authentik` используется как backend для пользователей, паролей и OIDC
- наше приложение не хранит пароль и не хранит password hash
- регистрация создаёт пользователя через `Authentik API`
- login выполняется backend-to-backend через `Authentik flow/executor API`
- после login backend получает `id_token` и `access_token` от `Authentik`
- токены не хранятся в `localStorage` или `sessionStorage`
- токены хранятся только в `HttpOnly` cookie с `SameSite=Lax`
- `/me` возвращает claims из JWT после валидации токена на backend
- `/dashboard` показывает claims из `/me`, без вывода raw JWT
- `docker-compose.yml` поднимает `postgresql`, `redis`, `authentik`, `authentik-worker` и `frontend`
- `authentik/blueprints/mm-custom-authentication-flow.yaml` создаёт flow, provider и application
- `frontend/server.js` содержит UI и логику регистрации/входа
## Что вне scope
- sessions UI
- consent UI
- MFA devices UI
- connected services
- app passwords
## Порты
Порты проброшены только на localhost:
- frontend: `http://localhost:3000`
- Authentik admin: `http://localhost:9000`
## Быстрый старт
```bash
docker compose up --build
```
Если нужно полностью пересобрать проект с чистыми данными:
```bash
docker compose down -v
docker compose up --build
```
Первый запуск Authentik может занять несколько минут. Нужно дождаться, пока `authentik-worker` применит blueprint.
## Удобный локальный `.env` для теста
Для быстрого ручного тестирования можно использовать такие локальные значения в `.env`:
1. Скопируй `.env.example` в `.env`
2. Для локального теста можно использовать такие значения:
```env
AUTHENTIK_IMAGE=docker.io/authentik/server
@@ -52,43 +50,61 @@ AUTHENTIK_BOOTSTRAP_PASSWORD=admin123456
AUTHENTIK_BOOTSTRAP_TOKEN=local-bootstrap-token-change-me
APP_URL=http://localhost:3000
SESSION_SECRET=local-session-secret-change-me
AUTHENTIK_PUBLIC_URL=http://localhost:9000
AUTHENTIK_INTERNAL_URL=http://host.docker.internal:9000
AUTHENTIK_API_TOKEN=local-bootstrap-token-change-me
AUTHENTIK_LOGIN_FLOW=mm-custom-authentication-flow
OIDC_CLIENT_ID=mm-custom-frontend
OIDC_CLIENT_SECRET=mm-custom-secret
OIDC_ISSUER=http://localhost:9000/application/o/mm-custom-frontend/
OIDC_REDIRECT_URI=http://localhost:3000/auth/callback
COOKIE_SECURE=false
AUTH_DEBUG=false
```
3. Запусти проект:
```bash
docker compose up --build
```
Если нужен полностью чистый запуск:
```bash
docker compose down -v
docker compose up --build
```
## Как зайти в админку Authentik
Открой:
```txt
http://localhost:9000
```
Логин администратора берётся из `.env`:
- email: значение `AUTHENTIK_BOOTSTRAP_EMAIL`
- password: значение `AUTHENTIK_BOOTSTRAP_PASSWORD`
Или
Для локального теста из примера выше:
```txt
admin@millionmiles.local
admin123456
email: admin@millionmiles.local
password: admin123456
```
## Что создаётся автоматически
## Как это работает
Blueprint создаёт:
1. Регистрация пользователя идёт через `Authentik API`
2. Пароль хранится в `Authentik`, не в нашем приложении
3. Login идёт через кастомную форму на нашем frontend
4. Backend проверяет логин/пароль через `Authentik flow/executor API`
5. После успешного login backend получает `id_token` и `access_token` от `Authentik`
6. Токены кладутся в `HttpOnly` cookie
7. `/me` читает токен из cookie, валидирует JWT и возвращает claims JSON
8. `/dashboard` показывает именно эти claims
## Что создаёт blueprint
```txt
Flow: Million Miles Custom Authentication
@@ -101,17 +117,26 @@ Client Secret: mm-custom-secret
Redirect URI: http://localhost:3000/auth/callback
```
## Как быстро всё протестировать
## Ручная проверка
1. Открой `http://localhost:3000/register`
2. Зарегистрируй нового пользователя
3. После регистрации тебя перекинет на `/login`
4. Войди с только что созданными `email/password`
5. После успешного входа откроется `/dashboard`
6. На dashboard увидишь данные пользователя из JWT `id_token`
3. Проверь, что форма требует:
`Полное имя`, `Email`, `Пароль`, `Подтвердите пароль`
4. Проверь валидацию пароля:
минимум 8 символов, одна заглавная, одна строчная, одна цифра
5. После регистрации перейди на `http://localhost:3000/login`
6. Войди через кастомную форму `email/password`
7. После входа открой `http://localhost:3000/me`
8. Убедись, что `/me` возвращает JSON с claims:
`sub`, `email`, `name`, `preferred_username`, `username`, `iss`, `aud`, `iat`, `exp`
9. Открой `http://localhost:3000/dashboard`
10. Убедись, что dashboard показывает claims без raw JWT
11. Нажми `Выйти` и проверь, что `POST /logout` очищает cookie и возвращает на `/login`
## Что проверить в админке
В Authentik admin можно проверить:
```txt
Applications -> Applications -> Million Miles
@@ -120,11 +145,8 @@ Flows and Stages -> Flows -> Million Miles Custom Authentication
Directory -> Users
```
## Если OIDC provider ещё не применился
## Важно
Если frontend пишет, что провайдер ещё не готов, проверь worker:
```bash
docker compose logs -f authentik-worker
```
- `COOKIE_SECURE=false` подходит только для локальной разработки по `http`
- в production нужно использовать `COOKIE_SECURE=true`