lepture / authlib

The ultimate Python library in building OAuth, OpenID Connect clients and servers. JWS,JWE,JWK,JWA,JWT included.
https://authlib.org/
BSD 3-Clause "New" or "Revised" License
4.49k stars 448 forks source link

Authlib 1.2.0 redirect_uri returns URL object instead of string #535

Closed rmblau closed 1 year ago

rmblau commented 1 year ago

Describe the bug

In 1.1.0 the redirect uri was a string, in 1.2.0 the same code breaks because the redirect_uri is a URL object. The docs do not mention this change nor can I locate documentation on how to utilize this object.

Error Stacks

starbudget            |     return await google.authorize_redirect(request, redirect_uri)
starbudget            |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
starbudget            |   File "/usr/local/lib/python3.11/site-packages/authlib/integrations/starlette_client/apps.py", line 29, in authorize_redirect
starbudget            |     rv = await self.create_authorization_url(redirect_uri, **kwargs)
starbudget            |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
starbudget            |   File "/usr/local/lib/python3.11/site-packages/authlib/integrations/base_client/async_app.py", line 105, in create_authorization_url
starbudget            |     return self._create_oauth2_authorization_url(
starbudget            |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
starbudget            |   File "/usr/local/lib/python3.11/site-packages/authlib/integrations/base_client/sync_app.py", line 265, in _create_oauth2_authorization_url
starbudget            |     url, state = client.create_authorization_url(
starbudget            |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
starbudget            |   File "/usr/local/lib/python3.11/site-packages/authlib/oauth2/client.py", line 153, in create_authorization_url
starbudget            |     uri = prepare_grant_uri(
starbudget            |           ^^^^^^^^^^^^^^^^^^
starbudget            |   File "/usr/local/lib/python3.11/site-packages/authlib/oauth2/rfc6749/parameters.py", line 66, in prepare_grant_uri
starbudget            |     return add_params_to_uri(uri, params)
starbudget            |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
starbudget            |   File "/usr/local/lib/python3.11/site-packages/authlib/common/urls.py", line 99, in add_params_to_uri
starbudget            |     query = add_params_to_qs(query, params)
starbudget            |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
starbudget            |   File "/usr/local/lib/python3.11/site-packages/authlib/common/urls.py", line 90, in add_params_to_qs
starbudget            |     return url_encode(qs)
starbudget            |            ^^^^^^^^^^^^^^
starbudget            |   File "/usr/local/lib/python3.11/site-packages/authlib/common/urls.py", line 28, in url_encode
starbudget            |     encoded.append((to_bytes(k), to_bytes(v)))
starbudget            |                                  ^^^^^^^^^^^
starbudget            |   File "/usr/local/lib/python3.11/site-packages/authlib/common/encoding.py", line 15, in to_bytes
starbudget            |     return bytes(x)
starbudget            |            ^^^^^^^^
starbudget            | TypeError: cannot convert 'URL' object to bytes

put error stacks here



**To Reproduce**

To reproduce, follow this https://docs.authlib.org/en/latest/client/starlette.html#routes-for-authorization. The code example no longer works.

**Expected behavior**

I expect it to behave like it did in 1.1.0 and redirect properly.

**Environment:**

 - OS: debian 11
 - Python Version: 3.11
 - Authlib Version: 1.2.0

**Additional context**

Add any other context about the problem here.
rmblau commented 1 year ago

Just noticed this is in fact a starlette bug, closing issue

aartaviab commented 1 year ago

do you have the github link of that Starlette bug? thanks

nurettn commented 1 year ago

@rmblau This PR seems not enough to resolve this error: #533

Jsalaz1989 commented 1 year ago

In my case wrapping the oauth.google.authorize_redirect() with str does the trick:

@app.get("/login/google")
async def login_via_google(request: Request):
    redirect_uri = request.url_for('auth_via_google')
    return await oauth.google.authorize_redirect(request, str(redirect_uri)) # wrap with str()
alvartabe commented 1 year ago

In my case wrapping the oauth.google.authorize_redirect() with str does the trick:

@app.get("/login/google")
async def login_via_google(request: Request):
    redirect_uri = request.url_for('auth_via_google')
    return await oauth.google.authorize_redirect(request, str(redirect_uri)) # wrap with str()

hey! thanks for this workaround, its also working for me!