FastAPI集成Authlib实现Google OAuth时遇URL转bytes类型错误
解决Authlib + FastAPI Google OAuth登录的TypeError: cannot convert 'URL' object to bytes错误
问题场景
使用Authlib和FastAPI实现Google OAuth登录功能,严格遵循Authlib官方FastAPI示例开发,仅替换了Google的client_id和client_secret,未修改其他代码,但调用登录接口时触发如下错误:
ERROR: Exception in ASGI application Traceback (most recent call last): File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/uvicorn/protocols/http/httptools_impl.py", line 436, in run_asgi result = await app( # type: ignore[func-returns-value] File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__ return await self.app(scope, receive, send) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/fastapi/applications.py", line 276, in __call__ await super().__call__(scope, receive, send) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/starlette/applications.py", line 122, in __call__ await self.middleware_stack(scope, receive, send) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/starlette/middleware/errors.py", line 184, in __call__ raise exc File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/starlette/middleware/errors.py", line 162, in __call__ await self.app(scope, receive, _send) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/starlette/middleware/sessions.py", line 86, in __call__ await self.app(scope, receive, send_wrapper) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 79, in __call__ raise exc File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 68, in __call__ await self.app(scope, receive, sender) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__ raise e File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__ await self.app(scope, receive, send) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/starlette/routing.py", line 718, in __call__ await route.handle(scope, receive, send) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/starlette/routing.py", line 276, in handle await self.app(scope, receive, send) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/starlette/routing.py", line 66, in app response = await func(request) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/fastapi/routing.py", line 237, in app raw_response = await run_endpoint_function( File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/fastapi/routing.py", line 163, in run_endpoint_function return await dependant.call(**values) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/main.py", line 41, in login return await oauth.google.authorize_redirect(request, redirect_uri) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/authlib/integrations/starlette_client/apps.py", line 29, in authorize_redirect rv = await self.create_authorization_url(redirect_uri, **kwargs) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/authlib/integrations/base_client/async_app.py", line 105, in create_authorization_url return self._create_oauth2_authorization_url( File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/authlib/integrations/base_client/sync_app.py", line 265, in _create_oauth2_authorization_url url, state = client.create_authorization_url( File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/authlib/oauth2/client.py", line 155, in create_authorization_url uri = prepare_grant_uri( File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/authlib/oauth2/rfc6749/parameters.py", line 66, in prepare_grant_uri return add_params_to_uri(uri, params) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/authlib/common/urls.py", line 99, in add_params_to_uri query = add_params_to_qs(query, params) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/authlib/common/urls.py", line 90, in add_params_to_qs return url_encode(qs) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/authlib/common/urls.py", line 28, in url_encode encoded.append((to_bytes(k), to_bytes(v))) File "/Users/alvartabe/Desktop/FastAPI-GoogleOAuth/venv/lib/python3.10/site-packages/authlib/common/encoding.py", line 15, in to_bytes return bytes(x) TypeError: cannot convert 'URL' object to bytes
错误原因
报错核心是Authlib版本与Starlette/FastAPI的URL对象兼容性问题:旧版Authlib的URL编码逻辑无法直接处理Starlette生成的URL对象(比如通过request.url_for()返回的结果),尝试将其转为bytes时触发类型错误。
修复方案
将传入authorize_redirect的redirect_uri从URL对象转为字符串即可:
- 找到登录接口中生成redirect_uri的代码,原代码可能为:
redirect_uri = request.url_for('auth') return await oauth.google.authorize_redirect(request, redirect_uri)
- 修改为将URL对象转为字符串:
redirect_uri = str(request.url_for('auth')) return await oauth.google.authorize_redirect(request, redirect_uri)
验证
修改后重新启动FastAPI服务,访问登录接口即可正常跳转到Google授权页面,错误不再出现。
内容的提问来源于stack exchange,提问作者Alvaro Artavia
相关产品推荐
相关产品推荐

