From 408749f34d8123f67964405c0ceee2322aecd1db Mon Sep 17 00:00:00 2001 From: Untone Date: Tue, 23 Sep 2025 17:14:47 +0300 Subject: [PATCH] =?UTF-8?q?-=20=F0=9F=9A=A8=20**Critical=20Fix**:=20=D0=98?= =?UTF-8?q?=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=BA?= =?UTF-8?q?=D1=80=D0=B8=D1=82=D0=B8=D1=87=D0=B5=D1=81=D0=BA=D0=B0=D1=8F=20?= =?UTF-8?q?=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B0=20OAuth=20=D0=BC=D0=B0?= =?UTF-8?q?=D1=80=D1=88=D1=80=D1=83=D1=82=D0=B8=D0=B7=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8=20-=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20HTTP=20handlers=20=D0=B2=D0=BC?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=BE=20GraphQL=20=D1=84=D1=83=D0=BD=D0=BA?= =?UTF-8?q?=D1=86=D0=B8=D0=B9=20-=20=F0=9F=94=92=20**OAuth=20X/Twitter**:?= =?UTF-8?q?=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20?= =?UTF-8?q?=D0=BE=D0=B1=D1=8F=D0=B7=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D1=8B=D0=B5=20scope=20`tweet.read=20users.read`=20-=20?= =?UTF-8?q?=F0=9F=94=92=20**OAuth=20Yandex**:=20=D0=94=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20scope=20`login:email=20login:i?= =?UTF-8?q?nfo=20login:avatar`=20-=20=F0=9F=94=92=20**OAuth=20Telegram**:?= =?UTF-8?q?=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BD?= =?UTF-8?q?=D0=B5=D0=B4=D0=BE=D1=81=D1=82=D0=B0=D1=8E=D1=89=D0=B8=D0=B9=20?= =?UTF-8?q?access=5Ftoken=5Furl=20=D0=B8=20scope=20-=20=F0=9F=93=9A=20**OA?= =?UTF-8?q?uth=20Documentation**:=20=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B4=D0=BB=D1=8F=20=D0=B2?= =?UTF-8?q?=D1=81=D0=B5=D1=85=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B0=D0=B9=D0=B4?= =?UTF-8?q?=D0=B5=D1=80=D0=BE=D0=B2=20=D1=81=20=D0=B0=D0=BA=D1=82=D1=83?= =?UTF-8?q?=D0=B0=D0=BB=D1=8C=D0=BD=D1=8B=D0=BC=D0=B8=20=D0=BD=D0=B0=D1=81?= =?UTF-8?q?=D1=82=D1=80=D0=BE=D0=B9=D0=BA=D0=B0=D0=BC=D0=B8=20=D0=B8=20?= =?UTF-8?q?=D1=82=D1=80=D0=B5=D0=B1=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F?= =?UTF-8?q?=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 5 +++ auth/oauth.py | 10 +++++ docs/auth/oauth.md | 97 +++++++++++++++++++++++++++++++++++++++++----- main.py | 6 +-- 4 files changed, 106 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e99a482f..f336edae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,11 @@ - 🔒 **OAuth X/Twitter**: Исправлен endpoint с `authors/me` на `users/me` - 🔒 **Session Cookies**: Автоматическое определение HTTPS через переменную окружения HTTPS_ENABLED - 🏷️ **Type Safety**: Исправлена ошибка в OAuth регистрации провайдеров +- 🚨 **Critical Fix**: Исправлена критическая ошибка OAuth маршрутизации - использование HTTP handlers вместо GraphQL функций +- 🔒 **OAuth X/Twitter**: Добавлены обязательные scope `tweet.read users.read` +- 🔒 **OAuth Yandex**: Добавлены scope `login:email login:info login:avatar` +- 🔒 **OAuth Telegram**: Добавлен недостающий access_token_url и scope +- 📚 **OAuth Documentation**: Обновлена документация для всех провайдеров с актуальными настройками и требованиями ## [0.9.21] - 2025-09-21 diff --git a/auth/oauth.py b/auth/oauth.py index 4dcedc10..d16b8cd9 100644 --- a/auth/oauth.py +++ b/auth/oauth.py @@ -100,10 +100,17 @@ PROVIDER_CONFIGS = { "access_token_url": "https://api.twitter.com/2/oauth2/token", "authorize_url": "https://twitter.com/i/oauth2/authorize", "api_base_url": "https://api.twitter.com/2/", + "client_kwargs": { + "scope": "tweet.read users.read", # Базовые scope для X API v2 + }, }, "telegram": { + "access_token_url": "https://oauth.telegram.org/auth/request", "authorize_url": "https://oauth.telegram.org/auth", "api_base_url": "https://api.telegram.org/", + "client_kwargs": { + "scope": "read", # Базовый scope для Telegram + }, }, "vk": { "access_token_url": "https://oauth.vk.com/access_token", @@ -117,6 +124,9 @@ PROVIDER_CONFIGS = { "access_token_url": "https://oauth.yandex.ru/token", "authorize_url": "https://oauth.yandex.ru/authorize", "api_base_url": "https://login.yandex.ru/info", + "client_kwargs": { + "scope": "login:email login:info login:avatar", # Scope для получения профиля + }, }, } diff --git a/docs/auth/oauth.md b/docs/auth/oauth.md index 608a526b..8275bbaa 100644 --- a/docs/auth/oauth.md +++ b/docs/auth/oauth.md @@ -7,13 +7,13 @@ ## 🚀 Быстрый старт ### Поддерживаемые провайдеры -- **Google** - OpenID Connect -- **GitHub** - OAuth 2.0 -- **Facebook** - Facebook Login -- **VK** - VK OAuth -- **Yandex** - Yandex OAuth -- **X (Twitter)** - OAuth 2.0 -- **Telegram** - Telegram Login +- **Google** ✅ - OpenID Connect (актуальные endpoints) +- **GitHub** ✅ - OAuth 2.0 (scope: read:user user:email) +- **Facebook** ✅ - Facebook Login API v18.0+ (scope: email public_profile) +- **VK** ✅ - VK OAuth API v5.199+ (scope: email) +- **X (Twitter)** ✅ - OAuth 2.0 API v2 (scope: tweet.read users.read) +- **Yandex** ✅ - Yandex OAuth (scope: login:email login:info login:avatar) +- **Telegram** ⚠️ - Telegram Login (специфическая реализация) ### Redis структура ```bash @@ -215,9 +215,25 @@ VK_OAUTH_CONFIG = { - Scope `email` необходим для получения email адреса - Redirect URI должен **точно совпадать** с настройками в приложении VK - Поддерживаются только HTTPS redirect URI в production + +### X (Twitter) OAuth +```python +X_OAUTH_CONFIG = { + "client_id": os.getenv("X_CLIENT_ID"), + "client_secret": os.getenv("X_CLIENT_SECRET"), + "auth_url": "https://twitter.com/i/oauth2/authorize", + "token_url": "https://api.twitter.com/2/oauth2/token", + "user_info_url": "https://api.twitter.com/2/users/me", + "scope": "tweet.read users.read" } ``` +**⚠️ Важные требования X:** +- Используйте **API v2** endpoints +- Scope `users.read` обязателен для получения профиля +- Email недоступен через публичное API +- Требуется верификация приложения для production + ### Yandex OAuth ```python YANDEX_OAUTH_CONFIG = { @@ -226,10 +242,32 @@ YANDEX_OAUTH_CONFIG = { "auth_url": "https://oauth.yandex.ru/authorize", "token_url": "https://oauth.yandex.ru/token", "user_info_url": "https://login.yandex.ru/info", - "scope": "login:email login:info" + "scope": "login:email login:info login:avatar" } ``` +**⚠️ Важные требования Yandex:** +- Scope `login:email` для получения email +- Scope `login:info` для базовой информации профиля +- Scope `login:avatar` для получения аватара +- Поддержка только HTTPS redirect URI + +### Telegram OAuth +```python +TELEGRAM_OAUTH_CONFIG = { + "client_id": os.getenv("TELEGRAM_CLIENT_ID"), + "client_secret": os.getenv("TELEGRAM_CLIENT_SECRET"), + "auth_url": "https://oauth.telegram.org/auth", + "token_url": "https://oauth.telegram.org/auth/request", + "scope": "read" +} +``` + +**⚠️ Важные требования Telegram:** +- Специальная настройка через @BotFather +- Email недоступен - используется временный email +- Получение номера телефона требует дополнительных разрешений + ## 🔒 Безопасность ### TTL и истечение токенов @@ -347,10 +385,21 @@ FACEBOOK_APP_SECRET=your_facebook_app_secret VK_APP_ID=your_vk_app_id VK_APP_SECRET=your_vk_app_secret +# X (Twitter) OAuth +X_CLIENT_ID=your_x_client_id +X_CLIENT_SECRET=your_x_client_secret + # Yandex OAuth YANDEX_CLIENT_ID=your_yandex_client_id YANDEX_CLIENT_SECRET=your_yandex_client_secret +# Telegram OAuth +TELEGRAM_CLIENT_ID=your_telegram_client_id +TELEGRAM_CLIENT_SECRET=your_telegram_client_secret + +# HTTPS настройки +HTTPS_ENABLED=true # false для разработки + # Redis для state management REDIS_URL=redis://localhost:6379/0 @@ -382,7 +431,37 @@ JWT_EXPIRATION_HOURS=24 2. Создать новое приложение 3. Добавить продукт "Facebook Login" 4. Настроить Valid OAuth Redirect URIs: - - `https://your-domain.com/auth/oauth/facebook/callback` + - `https://your-domain.com/oauth/facebook/callback` +5. Переключить приложение в режим "Live" + +#### X (Twitter) OAuth +1. Перейти в [Twitter Developer Portal](https://developer.twitter.com/en/portal/dashboard) +2. Создать новое приложение +3. Настроить OAuth 2.0 settings +4. Добавить Callback URLs: + - `https://your-domain.com/oauth/x/callback` +5. Получить Client ID и Client Secret + +#### VK OAuth +1. Перейти в [VK Developers](https://vk.com/dev) +2. Создать новое приложение типа "Веб-сайт" +3. Настроить "Доверенный redirect URI": + - `https://your-domain.com/oauth/vk/callback` +4. Получить ID приложения и Защищённый ключ + +#### Yandex OAuth +1. Перейти в [Yandex OAuth](https://oauth.yandex.ru/) +2. Создать новое приложение +3. Настроить Callback URL: + - `https://your-domain.com/oauth/yandex/callback` +4. Выбрать необходимые права доступа +5. Получить ID и пароль приложения + +#### Telegram OAuth +1. Создать бота через @BotFather +2. Получить Bot Token +3. Настроить OAuth через Telegram API +4. **Внимание**: Telegram OAuth имеет специфическую реализацию ### Redis команды для отладки ```bash diff --git a/main.py b/main.py index ed153f82..04a44142 100644 --- a/main.py +++ b/main.py @@ -18,7 +18,7 @@ from starlette.staticfiles import StaticFiles from auth.handler import EnhancedGraphQLHTTPHandler from auth.middleware import AuthMiddleware, auth_middleware -from auth.oauth import oauth_callback, oauth_login +from auth.oauth import oauth_callback_http, oauth_login_http from cache.precache import precache_data from cache.revalidator import revalidation_manager from rbac import initialize_rbac @@ -303,8 +303,8 @@ app = Starlette( routes=[ Route("/graphql", graphql_handler, methods=["GET", "POST", "OPTIONS"]), # OAuth маршруты - Route("/oauth/{provider}", oauth_login, methods=["GET"]), - Route("/oauth/{provider}/callback", oauth_callback, methods=["GET"]), + Route("/oauth/{provider}", oauth_login_http, methods=["GET"]), + Route("/oauth/{provider}/callback", oauth_callback_http, methods=["GET"]), # Health check endpoint Route("/health", health_handler, methods=["GET"]), # Статические файлы (CSS, JS, изображения)