Replies: 2 comments
-
Hi @HBrendy 👋 Thank you for your feedback and detailed explanations! Your explanations enlighten something I never saw before: the way we expect httpx-oauth/httpx_oauth/integrations/fastapi.py Lines 75 to 82 in 26761ec This is executed by FastAPI when the callback route is called. Here, it's implemented as if the A working approach would be to expect the end-developer to provide its own function or method to retrieve the Now, regarding your approach, sounds reasonable. Maybe what's a bit surprising is that you use the I agree Final side note: PKCE was primarily designed for public OAuth2 clients, where you can't use the |
Beta Was this translation helpful? Give feedback.
-
Hi @frankie567 , thank for your instant response! Work carried me away the in last days, but now I can finally reply:
Have a great weekend! |
Beta Was this translation helpful? Give feedback.
-
Dear François (@frankie567),
thank you for this great library! I'm using it in for an open source project in a public health context and it helped me a lot.
I'm using the Github httpx-oauth client alongside my self-written Gitlab httpx-oauth client for our self-hosted Gitlab instance. While Github does not (yet?) support PKCE, Gitlab does and it worked almost out of the box:
TLDR
I generate the PKCE code verifiers & challenges on a per-request basis.
To match an incoming callback (including a
state
JWT) to acode_verifier
, I put thecode_challenge
into the state JWT upon generating the authentication URL.For this to work, the state JWT needs to be handed over to the class function get_access_token() of the dependency httpx_oauth.integrations.fastapi.OAuth2AuthorizeCallback:
Reasoning / Background
My current stack includes httpx-oauth v0.16.1, fastapi-users[beanie,redis,oauth] v14.0.1 and fastapi v0.115.6.
To store the code verifier & challenge in the fastapi backend, I created a class similar to fastapi-users RedisStrategy within my
httpx_oauth/clients/gitlab.py
that handles secret generation, challenge derivation and stores both in REDIS as a key:value pair:The code_challenge is then added to the state before responding to a
get_authorization_url()
request and also acts as an identifier when the callback is triggered.It is a bit hacky to decode the state JWT, add the code_challenge and encode it again, but this way, all logic is confined to the client class [BaseOAuth2].
I still went down that road to get one-time-code_verifiers for trading in access tokens for Authorization Codes.
For this, my custom
client.get_access_token()
needs thestate
JWT to exctract the code_challenge to look up the code_verifier in REDIS before sending it to the Authorization Server.Benefits:
With above mokey patch, I have a working Oauth2 with PKCE against Gitlab :-)
What do you think of this approach?
Shall I wrap it as a MR?
Cheers from Berlin,
Holger
Beta Was this translation helpful? Give feedback.
All reactions