This commit is contained in:
@@ -680,6 +680,14 @@ async def oauth_callback_http(request: Request) -> JSONResponse | RedirectRespon
|
||||
client = oauth.create_client(provider)
|
||||
if not client:
|
||||
logger.warning(f"🚨 OAuth provider {provider} not configured - returning graceful error")
|
||||
# Проверяем конфигурацию провайдера
|
||||
from settings import OAUTH_CLIENTS
|
||||
|
||||
provider_config = OAUTH_CLIENTS.get(provider.upper(), {})
|
||||
logger.error(
|
||||
f"🚨 OAuth config for {provider}: client_id={'***' if provider_config.get('id') else 'MISSING'}, client_secret={'***' if provider_config.get('key') else 'MISSING'}"
|
||||
)
|
||||
|
||||
# Graceful fallback: редиректим на фронтенд с информативной ошибкой
|
||||
redirect_uri = oauth_data.get("redirect_uri", FRONTEND_URL)
|
||||
error_url = f"{redirect_uri}?error=provider_not_configured&provider={provider}&message=OAuth+provider+credentials+missing"
|
||||
@@ -692,6 +700,9 @@ async def oauth_callback_http(request: Request) -> JSONResponse | RedirectRespon
|
||||
|
||||
# 🔍 Обмениваем code на токен - с PKCE или без в зависимости от провайдера
|
||||
logger.info("🔄 Step 1: Exchanging authorization code for access token...")
|
||||
logger.info(f"🔧 Authorization response URL: {request.url}")
|
||||
logger.info(f"🔧 Code parameter: {code[:20]}..." if code and len(code) > 20 else f"🔧 Code parameter: {code}")
|
||||
|
||||
try:
|
||||
if provider in ["vk", "yandex", "telegram", "facebook"]:
|
||||
# Провайдеры без PKCE поддержки (Facebook может иметь проблемы с PKCE)
|
||||
@@ -707,12 +718,15 @@ async def oauth_callback_http(request: Request) -> JSONResponse | RedirectRespon
|
||||
return JSONResponse({"error": "Missing code verifier in OAuth state"}, status_code=400)
|
||||
|
||||
logger.info(f"🔧 Using OAuth with PKCE for {provider}")
|
||||
logger.info(f"🔧 Code verifier length: {len(code_verifier) if code_verifier else 0}")
|
||||
token = await client.fetch_access_token(
|
||||
authorization_response=str(request.url),
|
||||
code_verifier=code_verifier,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"❌ Failed to fetch access token for {provider}: {e}", exc_info=True)
|
||||
logger.error(f"❌ Request URL: {request.url}")
|
||||
logger.error(f"❌ OAuth data: {oauth_data}")
|
||||
raise # Re-raise для обработки в основном except блоке
|
||||
if not token:
|
||||
logger.error(f"❌ Failed to get access token for {provider}")
|
||||
@@ -848,9 +862,30 @@ async def oauth_callback_http(request: Request) -> JSONResponse | RedirectRespon
|
||||
logger.error(f"OAuth callback error for {provider}: {e!s}", exc_info=True)
|
||||
logger.error(f"OAuth callback request URL: {request.url}")
|
||||
logger.error(f"OAuth callback query params: {dict(request.query_params)}")
|
||||
|
||||
# В случае ошибки редиректим на фронтенд с ошибкой
|
||||
fallback_redirect = request.query_params.get("redirect_uri", FRONTEND_URL)
|
||||
return RedirectResponse(url=f"{fallback_redirect}?error=auth_failed&provider={provider}")
|
||||
# Используем сохраненный redirect_uri из OAuth state или fallback
|
||||
try:
|
||||
state = request.query_params.get("state")
|
||||
oauth_data = await get_oauth_state(state) if state else None
|
||||
fallback_redirect = oauth_data.get("redirect_uri") if oauth_data else FRONTEND_URL
|
||||
except Exception:
|
||||
fallback_redirect = FRONTEND_URL
|
||||
|
||||
# Обеспечиваем что fallback_redirect это строка
|
||||
if not isinstance(fallback_redirect, str):
|
||||
fallback_redirect = FRONTEND_URL
|
||||
|
||||
# Для testing.discours.io используем специальный формат
|
||||
if "testing.discours.io" in fallback_redirect:
|
||||
from urllib.parse import quote
|
||||
|
||||
error_url = f"https://testing.discours.io/oauth?error=auth_failed&provider={provider}&redirect_url={quote(fallback_redirect)}"
|
||||
else:
|
||||
error_url = f"{fallback_redirect}?error=auth_failed&provider={provider}"
|
||||
|
||||
logger.error(f"🚨 Redirecting to error URL: {error_url}")
|
||||
return RedirectResponse(url=error_url)
|
||||
|
||||
|
||||
async def _create_or_update_user(provider: str, profile: dict) -> Author:
|
||||
|
||||
Reference in New Issue
Block a user