5.2 KiB
5.2 KiB
Yandex ID + VK ID OAuth — Design
Цель
Подключить авторизацию через Яндекс ID и VK ID на клиенте (серверная часть OAuth уже реализована). Добавить поля профиля: имя, фамилия, пол, аватар. Админ продолжает входить только через email/код.
Объём
База данных
- Переименовать
User.name→User.displayName - Добавить поля:
firstName String?,lastName String?,gender String?,avatar String? - Сбросить БД (
prisma migrate reset --force), прода нет
Сервер
server/prisma/schema.prisma— обновить модель Userserver/src/routes/oauth-social.js— обновитьfindOrCreateUserFromOAuth():- Яндекс: сохранять
firstName,lastName,gender(sex),avatar(https://avatars.yandex.net/get-yapic/{default_avatar_id}/islands-200),displayName←real_nameилиdisplay_name - VK: сохранять
firstName(first_name),lastName(last_name),gender(sex: 1→female, 2→male),avatar(photo_200),displayName←first_name + ' ' + last_name - Gender: если провайдер не вернул — оставлять
null
- Яндекс: сохранять
server/src/routes/auth.js— обновитьmapUserForClient(): добавить новые поля в ответ/api/me; переименоватьname→displayNameserver/src/**/*.js— найти и заменить все использованияuser.nameнаuser.displayNameserver/.env.example— документировать redirect URI для Яндекс и VK
Клиент
client/src/shared/model/auth.ts— обновить типAuthUser, добавитьdisplayName,firstName,lastName,gender,avatar; убратьnameclient/src/features/auth-oauth/— новая FSD-фича:lib/oauth-providers.ts— конфигурация:{ id, label, icon, color }для yandex и vkui/OAuthButtons.tsx— компонент с двумя кнопками (Stack + Button variant="outlined"), каждая редиректит на/api/auth/oauth/{provider}index.ts— barrel экспорт
client/src/pages/auth/ui/AuthPage.tsx— добавить<OAuthButtons />после формы email-кода, разделив Divider'ом с текстом «или»client/src/**/*.tsx— найти и заменить все использованияuser.name→user.displayName
ENV
Переменные в server/.env (из примера):
SERVER_PUBLIC_URL=http://127.0.0.1:3333
CLIENT_PUBLIC_URL=http://127.0.0.1:5173
YANDEX_CLIENT_ID=<значение>
YANDEX_CLIENT_SECRET=<значение>
VK_CLIENT_ID=<значение>
VK_CLIENT_SECRET=<значение>
Redirect URI для настройки в кабинетах провайдеров:
- Яндекс (локально):
http://127.0.0.1:3333/api/auth/oauth/yandex/callback - VK (локально):
http://127.0.0.1:3333/api/auth/oauth/vk/callback - Яндекс (прод):
https://любимыйкреатив.рф/api/auth/oauth/yandex/callback - VK (прод):
https://любимыйкреатив.рф/api/auth/oauth/vk/callback
Структура фичи features/auth-oauth/
features/auth-oauth/
index.ts — barrel: export { OAuthButtons }
ui/
OAuthButtons.tsx — Stack из 2 кнопок (Яндекс, VK)
lib/
oauth-providers.ts — массив провайдеров: { id, label, icon, color }
Data flow (OAuth)
Клиент: кнопка «Войти через Яндекс/VK»
→ редирект на /api/auth/oauth/{yandex|vk}
Сервер: формирует state JWT, редиректит на Яндекс/VK
→ пользователь авторизуется у провайдера
→ провайдер редиректит на /api/auth/oauth/{yandex|vk}/callback
Сервер: обменивает code на токен → получает профиль → findOrCreateUserFromOAuth()
→ генерирует JWT → редиректит на {CLIENT_PUBLIC_URL}/auth/callback?token=<jwt>
Клиент: AuthCallbackPage читает token → сохраняет в localStorage → редирект на /
Не входит в scope
- Отображение аватара в хедере/UserMenu (будет отдельно)
- Страница профиля с новыми полями (будет отдельно)
- OAuth для админа (админ только email/код)
Примечания
gender— nullable, если провайдер не вернул пол- VK:
sex: 1= female,sex: 2= male → нормализуем вfemale/male - Яндекс: avatar — конструируем URL из
default_avatar_id, полеis_avatar_emptyподскажет, загружен ли аватар - Яндекс scopes:
login:email login:info - VK scopes:
email - OAuth state — JWT с
expiresIn: 15m