нашим OAuth2-сервером.
                  
                  
                  Но есть нюанс.
                  
                  
                  Вот код одного из классов:
                  
                  
                  https://github.com/lepture/authlib/blob/master/authlib/oauth2/rfc6749/wrappers.py#L9
                  
                  
                      def __init__(self, params):
                  
                  
                          if params.get('expires_at'):
                  
                  
                              params['expires_at'] = int(params['expires_at'])
                  
                  
                          elif params.get('expires_in'):
                  
                  
                              params['expires_at'] = int(time.time()) + \
                  
                  
                                                     int(params['expires_in'])
                  
                  
                          super(OAuth2Token, self).__init__(params)
                  
                  
                  
                  
                  
                  Наш собственный OAuth2-сервер написан кривовато, и отдаёт поле expires_at как строку в ISO-формате, а не как unixtime.
                  
                  
                  Решение-то простое:
                  
                  
                  params['expires_at'] = int(datetime.strptime(params['expires_at'], '%Y-%m-%dT%H:%M:%S').timestamp())
                  
                  
                  
                  
                  
                  Но я теперь не понимаю, как подменить исходный объект новым.
                  
                  
                  Что пробовал:
                  
                  
                  1. Сделать класс MockedOAuth2Token и попробовать подменить:
                  
                  
                  oauth2.rfc6749.wrappers.OAuth2Token = MockedOAuth2Token
                  
                  
                  Не работает
                  
                  
                  
                  
                  
                  2. Переделать только __init__ и через unittest.mock запатчить.
                  
                  
                  Пробовал разными способами, тоже не работает. Ошибки больше нет, но данные пропадают по дороге, из-за чего всё бесполезно.
                  
                  
                  
                  
                  
                  Есть какие-то удобные решения, кроме форка библиотеки?
                  
                  
                
 Groosha
                          
                        
                      
                    
                    
                    
                    
                      Автор вопроса
                      
                      
                        
                          Groosha
                          
                        
                      
                    
                    
                    
                    
                      Автор вопроса
                    
                    
                  Приложение на FastAPI. Ручка для начала авторизации: @router.get("/") async def login( request: Request, authorization: str = Cookie(default=None, alias="Authorization"), ): client = oauth.create_client("profile") redirect_uri = request.url_for('oauth_callback_get') return await client.authorize_redirect(request, redirect_uri) В момент нажатия юзером кнопки Allow: @router.get("/callback") async def oauth_callback_get(request: Request): OAuth2Client.token_auth_class = MockedOAuth2Token client = oauth.create_client("profile") client.token_auth_class = MockedOAuth2Token token = await client.authorize_access_token(request) # тут крашится из-за конвертации Что касается profile: oauth = OAuth() oauth.register( name="profile", client_id=config.client_id, client_secret=config.client_secret.get_secret_value(), authorize_url="https://our.corporate.domain/oauth/authorize", access_token_url="https://our.corporate.domain/oauth/token", client_kwargs={ "scope": "profile_user default groups" } )
 Groosha
                          
                        
                      
                    
                    
                    
                    
                      Автор вопроса
                      
                      
                        
                          Groosha
                          
                        
                      
                    
                    
                    
                    
                      Автор вопроса
                    
                    
                  Решил! def profile_compiance_fix(session): def _fix(resp): resp.raise_for_status() token = resp.json() token["expires_at"] = int(datetime.strptime(token["expires_at"], "%Y-%m-%dT%H:%M:%S").timestamp()) resp._content = json.dumps(token).encode('utf-8') return resp session.register_compliance_hook('access_token_response', _fix) oauth = OAuth() oauth.register( name="profile", client_id=config.client_id, client_secret=config.client_secret.get_secret_value(), authorize_url="https://our.corporate.domain/oauth/authorize", access_token_url="https://our.corporate.domain/oauth/token", compliance_fix=profile_compiance_fix, client_kwargs={ "scope": "profile_user default groups" } ) Спасибо @Tishka17 за наводку) И вот этой еле найденной странице в доке
Обсуждают сегодня