Аутентификация
Laminara не хранит аккаунты. Логины и пароли остаются там, где они у вас уже есть — в базе сайта, в отдельном файле или за вашим API. Laminara обращается к этому источнику через адаптер, проверяет пару логин/пароль и владеет только сессиями.
Раздел auth состоит из трёх частей: провайдер (откуда аккаунты), хеш пароля и хранилище сессий.
Провайдеры
Аккаунты в JSON-файле. Годится для небольшого списка или на старте.
{ "provider": "jsonfile", "config": { "path": "/var/lib/laminara/users.json", "hash": "argon2id", "fields": { "username": "username", "password": "password", "uuid": "uuid" } }, "sessions": { "backend": "memory" }}Сам файл — массив объектов; fields задаёт, какие ключи считать логином, паролем и (необязательно) UUID.
Аккаунты в вашей базе — Postgres или MySQL. Laminara только читает.
{ "provider": "sql", "config": { "driver": "postgres", "dsn": "postgres://ro:pass@db:5432/site?sslmode=disable", "table": "users", "hash": "bcrypt", "fields": { "username": "nickname", "password": "password_hash", "uuid": "uuid" } }, "sessions": { "backend": "redis", "redisAddr": "redis:6379" }}fields сопоставляет логические поля с колонками вашей таблицы — подстраивать чужую схему под Laminara не нужно. Имена таблицы и колонок проверяются, произвольный SQL в них не подставить.
Если одной таблицей не обойтись — пароли лежат отдельно, есть флаг бана, нужен вид — задайте запрос сами вместо table и fields:
{ "provider": "sql", "config": { "driver": "mariadb", "dsn": "laminara:pass@tcp(127.0.0.1:3306)/site?charset=utf8mb4", "hash": "argon2id", "query": "SELECT p.hash, u.uuid FROM users u JOIN user_passwords p ON p.user_id = u.id WHERE u.username = ? AND u.is_banned = 0" }}Запрос принимает логин единственным подстановочным знаком (? для MySQL и MariaDB, $1 для Postgres) и выбирает сначала пароль, затем при желании UUID. Ничего кроме этих двух колонок возвращать не нужно.
Так же решается и бан: условие живёт в вашей схеме, и только ваш запрос может его учесть. Игрок, помеченный забаненным на сайте, просто не найдётся — и не войдёт.
Проверку логина делает ваш сервис — Laminara шлёт ему запрос.
{ "provider": "http", "config": { "url": "https://site.example/api/auth", "usernameField": "login", "passwordField": "password", "uuidField": "uuid", "successField": "ok" }, "sessions": { "backend": "redis", "redisAddr": "redis:6379" }}Laminara кладёт логин и пароль в указанные поля запроса, считает вход успешным по полю successField в ответе и берёт оттуда же UUID.
Хеш пароля
Поле hash (у jsonfile и sql) говорит, как пароль захеширован в вашем источнике. Laminara хеширует введённый пароль тем же способом и сравнивает. Доступны:
argon2id · bcrypt · sha256 · sha512 · md5 · plain
Сессии
Пароль проверяется один раз; дальше клиент живёт по токенам, которые выдаёт и хранит Laminara. Токен доступа короткий, токен обновления — длинный. При обновлении старый токен отзывается, а попытка воспользоваться отозванным распознаётся.
backend: "memory"— сессии в памяти процесса. Просто, но не переживают перезапуск и не годятся для нескольких экземпляров.backend: "redis"сredisAddr— сессии в Redis: переживают перезапуск и общие для нескольких экземпляров сервера.
Сроки жизни токенов задаются полями accessTTL и refreshTTL рядом с provider (например, "15m" и "720h").