Authlib + mailchimp oauth2: инвалид_клиент: отсутствует параметр client_idPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Authlib + mailchimp oauth2: инвалид_клиент: отсутствует параметр client_id

Сообщение Anonymous »

Я создаю фабрику OAuth2, используя authlib и FastAPI, поскольку моему вышестоящему приложению необходимо проходить аутентификацию у нескольких поставщиков.
Фабрика аутентификации хорошо работает со всеми поставщиками, кроме Mailchimp.< /p>
Я не хочу использовать клиентскую библиотеку mailchimp_marketing (по нескольким причинам).
Когда я инициирую поток OAuth в браузере, В конечном итоге я получаю следующую ошибку в своей функции обратного вызова на токене = await oauth_client.authorize_access_token(request) (обмен кода авторизации на токен доступа). И я подтвердил, что «client_id=settings.MAILCHIMP_CLIENT_ID» действительно установлен.

Код: Выделить всё

"GET /oauth/mailchimp/callback?state=ABC123XYZ&code=ABC123XYZ HTTP/1.1" 500 Internal

Server Error
...
2024-07-07 16:48:30   File "/app/app/api/oauth.py", line 25, in callback
2024-07-07 16:48:30     token = await oauth_client.authorize_access_token(request)
2024-07-07 16:48:30   File "/usr/local/lib/python3.9/site-packages/authlib/integrations/starlette_client/apps.py", line 81, in authorize_access_token
2024-07-07 16:48:30     token = await self.fetch_access_token(**params, **kwargs)
2024-07-07 16:48:30   File "/usr/local/lib/python3.9/site-packages/authlib/integrations/base_client/async_app.py", line 125, in fetch_access_token
2024-07-07 16:48:30     token = await client.fetch_token(token_endpoint, **params)
2024-07-07 16:48:30   File "/usr/local/lib/python3.9/site-packages/authlib/integrations/httpx_client/oauth2_client.py", line 138, in _fetch_token
2024-07-07 16:48:30     return self.parse_response_token(resp)
2024-07-07 16:48:30   File "/usr/local/lib/python3.9/site-packages/authlib/oauth2/client.py", line 344, in parse_response_token
2024-07-07 16:48:30     raise self.oauth_error_class(
2024-07-07 16:48:30 authlib.integrations.base_client.errors.OAuthError: invalid_client: client_id parameter missing
Вот мой соответствующий код:
provider_factory.py

Код: Выделить всё

# app/services/provider_factory.py

from authlib.integrations.starlette_client import OAuth
from app.core.config import settings
from sqlalchemy.orm import Session

class ProviderFactory:
oauth = OAuth()
oauth.register(
name='mailchimp',
client_id=settings.MAILCHIMP_CLIENT_ID,
client_secret=settings.MAILCHIMP_CLIENT_SECRET,
authorize_url='https://login.mailchimp.com/oauth2/authorize',
access_token_url='https://login.mailchimp.com/oauth2/token',
api_base_url='https://login.mailchimp.com/oauth2/',
)

oauth.register(
name='another_provider',
client_id=settings.ANOTHER_CLIENT_ID,
client_secret=settings.ANOTHER_CLIENT_SECRET,
authorize_url='https://auth.another.com/oauth2/authorize',
access_token_url='https://auth.another.com/oauth2/token',
client_kwargs={'scope': '...'},
)

@staticmethod
def get_provider_service(provider_name: str, db: Session):
from app.models.provider import Provider
provider = db.query(Provider).filter_by(name=provider_name).first()
if not provider:
raise ValueError(f"No provider found with name: {provider_name}")

if provider.name == 'mailchimp':
from app.services.mailchimp import MailchimpProvider
return MailchimpProvider(db, provider)
elif provider.name == 'another':
from app.services.another import AnotherProvider
return AnotherProvider(db, provider)
else:
raise ValueError(f"Unsupported provider: {provider.name}")

@staticmethod
def get_oauth_client(provider_name: str):
return getattr(ProviderFactory.oauth, provider_name)

@staticmethod
def get_token_url(provider_name: str) ->  str:
if provider_name == 'mailchimp':
return 'https://login.mailchimp.com/oauth2/token'
elif provider_name == 'another':
return 'https://auth.another.com/oauth2/token'
else:
raise ValueError("Unsupported provider")

@staticmethod
def create_provider(db: Session, provider_name: str):
return ProviderFactory.get_provider_service(provider_name, db)
oauth.py

Код: Выделить всё

# app/api/oauth.py

from fastapi import APIRouter, Depends, HTTPException, Request
from sqlalchemy.orm import Session
from app.db.session import get_db
from app.models.provider import Provider
from app.models.user import User
from app.models.connection import Connection
from app.core.logger import logger
from app.services.provider_factory import ProviderFactory

router = APIRouter()

@router.get("/{provider}/login")
async def login(provider: str, request: Request):
redirect_uri = request.url_for('callback', provider=provider)
return await ProviderFactory.get_oauth_client(provider).authorize_redirect(request, redirect_uri)

@router.get("/{provider}/callback")
async def callback(provider: str, request: Request, db: Session = Depends(get_db)):
logger.info(f"Provider: {provider}")
logger.info(f"Request query params: {request.query_params}")

oauth_client = ProviderFactory.get_oauth_client(provider)
token = await oauth_client.authorize_access_token(request)
if not token:
raise HTTPException(status_code=400, detail="Failed to get access token")

provider_record = db.query(Provider).filter_by(name=provider).first()
if not provider_record:
raise HTTPException(status_code=400, detail="Provider not found")

provider_service = ProviderFactory.get_provider_service(provider, db)

# Get user information from the provider
user_info = await provider_service.get_account_info(token)
logger.info(f"User info: {user_info}")

...

return {"status": "success", "provider": provider}
mailchimp.py

Код: Выделить всё

# app/services/mailchimp.py

import requests
from app.services.base_provider import BaseProvider
from app.models.list import List
from app.models.list_properties import ListProperties

class MailchimpProvider(BaseProvider):
tokens_expire = False

async def get_account_info(self, token: dict):
async with aiohttp.ClientSession() as session:
headers = {'Authorization': f'Bearer {token["access_token"]}'}
async with session.get('https://login.mailchimp.com/oauth2/metadata', headers=headers) as response:
return await response.json()

async def get_lists(self):
headers = {
'Authorization': f'Bearer {self.provider.access_token}'
}
response = requests.get('https://api.mailchimp.com/3.0/lists', headers=headers)
lists_data = response.json().get('lists', [])

for list_data in lists_data:
...

...
Есть идеи? Надеюсь, я просто упускаю что-то маленькое.

Подробнее здесь: https://stackoverflow.com/questions/787 ... er-missing
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»