Files
voidea/docs/backlog/oauth-schema-note.md

145 lines
4.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OAuth Schema - VoIdea
**Дата:** 2026-05-10
**Статус:** Backlog (для фиксации ADR)
---
## Обзор
Схема авторизации: один пользователь = один провайдер. Нельзя привязать Google если уже есть Яндекс.
---
## Правила
### Основное правило
> Один пользователь = один провайдер (email или OAuth)
Это означает:
- Если зарегистрировался через Яндекс → только Яндекс
- Если зарегистрировался через Google → только Google
- Если зарегистрировался через email → только email + пароль
### Нельзя
- Привязать Google к аккаунту зарегистрированному через Яндекс
- Добавить второй OAuth провайдер
- Изменить email после регистрации через OAuth
---
## Структура данных
### Users table
```sql
CREATE TABLE users (
id UUID PRIMARY KEY,
email VARCHAR(255) UNIQUE,
password_hash VARCHAR(255), -- NULL если OAuth-only
-- OAuth данные (один провайдер)
oauth_provider VARCHAR(20), -- yandex|google|apple|null
oauth_id VARCHAR(255), -- ID в системе провайдера
-- Метаданные
email_verified BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW(),
-- Constraints
CONSTRAINT users_oauth_xor_email CHECK (
(oauth_provider IS NOT NULL AND email IS NOT NULL) OR
(oauth_provider IS NULL AND email IS NOT NULL AND password_hash IS NOT NULL)
)
);
CREATE UNIQUE INDEX uq_users_oauth ON users(oauth_provider, oauth_id) WHERE oauth_provider IS NOT NULL;
```
### Почему один провайдер
1. **Безопасность** — меньше точек входа
2. **Простота** — не нужно merge аккаунтов
3. **Ясность** — пользователь знает что использует
4. **Privacy** — данные не смешиваются между провайдерами
---
## OAuth Flow
### Яндекс
```
1. Пользователь нажимает "Войти через Яндекс"
2. Редирект на Яндекс OAuth
3. Callback с code
4. Получение access_token
5. Получение данных пользователя
6. Поиск/создание user по oauth_provider + oauth_id
7. Создание JWT session
```
### Google
Аналогично Яндексу, с заменой endpoint-ов.
---
## Регистрация через email
```sql
-- При регистрации через email
INSERT INTO users (email, password_hash, oauth_provider, oauth_id)
VALUES ('user@example.com', 'hash123', NULL, NULL);
```
### Вход через email
```sql
-- Проверка пароля
SELECT * FROM users WHERE email = 'user@example.com' AND password_hash = verify('hash123');
```
---
## Защита от привязки чужого аккаунта
### Проблема
Злоумышленник может попытаться привязать Google к чужому email.
### Решение
1. **Email verification** — требуется подтверждение
2. **Password check** — для существующих пользователей
3. **Separate tables** — OAuth и email разделены логически
---
## Будущее (Apple OAuth)
### Apple будет реализован позже
Для Apple потребуется:
- App Store Developer Account
- Private Key для подписи
- Тот же принцип: один пользователь = один провайдер
---
## TODO
- [ ] Реализовать OAuth service
- [ ] Интегрировать Яндекс OAuth
- [ ] Интегрировать Google OAuth
- [ ] Зарезервировать место для Apple (не реализовывать)
- [ ] Тесты
- [ ] Документация
---
*Создано: 2026-05-10*
*См. также: docs/adr/003-oauth-schema.md*