feat(auth): вход через VK ID и Яндекс ID
Владельцу нужны VK и Яндекс (Google/Discord/GitHub остаются в каталоге и включаются своими ключами). VK ID (id.vk.ru, OAuth 2.1): - обязательный PKCE: code_challenge в запросе авторизации, code_verifier при обмене; верификатор выводится из подписанного state (HMAC), хранить нечего; - device_id из callback уходит в обмен кода; - для конфиденциальных приложений секрет передаётся как service_token, а не client_secret (и обмен идёт параметрами в теле, не Basic); - профиль: POST /oauth2/user_info с client_id и access_token; права email и vkid.personal_info. Яндекс ID: - права login:email и login:info; секрет — в теле запроса обмена; - профиль: GET login.yandex.ru/info?format=json с заголовком "Authorization: OAuth <токен>" (не Bearer). Общее: - в профиль добавлено DisplayName: VK отдаёт имя и фамилию, Яндекс — real_name, раньше они терялись; - почта считается подтверждённой, если провайдер её отдал (отдельного флага нет, адрес приходит только по соответствующему праву) — D-083; - новые переменные OAUTH_VK_* и OAUTH_YANDEX_* в установщике и .env.example; - тесты: полные флоу обоих провайдеров на мок-серверах, каталог и ручки.
This commit is contained in:
@@ -64,6 +64,10 @@ type Config struct {
|
||||
RetainInterval time.Duration
|
||||
// OAuth-провайдеры (AGENT.md 7.1, Фаза 7): включаются парами
|
||||
// client id/secret, пустые значения означают «провайдер выключен».
|
||||
OAuthVKClientID string
|
||||
OAuthVKClientSecret string
|
||||
OAuthYandexClientID string
|
||||
OAuthYandexClientSecret string
|
||||
OAuthGitHubClientID string
|
||||
OAuthGitHubClientSecret string
|
||||
OAuthGoogleClientID string
|
||||
@@ -121,6 +125,10 @@ func Load() (Config, error) {
|
||||
RetainOrphanHours: envInt("RETENTION_ORPHAN_HOURS", 24),
|
||||
RetainInterval: time.Duration(envInt("RETENTION_INTERVAL_SECONDS", 3600)) * time.Second,
|
||||
|
||||
OAuthVKClientID: env("OAUTH_VK_CLIENT_ID", ""),
|
||||
OAuthVKClientSecret: env("OAUTH_VK_CLIENT_SECRET", ""),
|
||||
OAuthYandexClientID: env("OAUTH_YANDEX_CLIENT_ID", ""),
|
||||
OAuthYandexClientSecret: env("OAUTH_YANDEX_CLIENT_SECRET", ""),
|
||||
OAuthGitHubClientID: env("OAUTH_GITHUB_CLIENT_ID", ""),
|
||||
OAuthGitHubClientSecret: env("OAUTH_GITHUB_CLIENT_SECRET", ""),
|
||||
OAuthGoogleClientID: env("OAUTH_GOOGLE_CLIENT_ID", ""),
|
||||
@@ -206,12 +214,14 @@ func (c Config) WebAuthnEnabled() bool {
|
||||
|
||||
// OAuthProviders перечисляет включённые провайдеры в стабильном порядке.
|
||||
func (c Config) OAuthProviders() []string {
|
||||
providers := make([]string, 0, 3)
|
||||
providers := make([]string, 0, 5)
|
||||
for _, candidate := range []struct {
|
||||
id string
|
||||
client string
|
||||
secret string
|
||||
}{
|
||||
{"vk", c.OAuthVKClientID, c.OAuthVKClientSecret},
|
||||
{"yandex", c.OAuthYandexClientID, c.OAuthYandexClientSecret},
|
||||
{"github", c.OAuthGitHubClientID, c.OAuthGitHubClientSecret},
|
||||
{"google", c.OAuthGoogleClientID, c.OAuthGoogleClientSecret},
|
||||
{"discord", c.OAuthDiscordClientID, c.OAuthDiscordClientSecret},
|
||||
|
||||
Reference in New Issue
Block a user