fastapi-sso
fastapi-sso copied to clipboard
LinkedIn SSO hanging on getting accessToken
Hey,
I have built a FastAPI app that is deployed on a Google Cloud Run instance, connected with a given subdomain. The app allows users to signing using both Google and LinkedIn. I am powering that functionality with fastapi-sso library but I am getting an issue with the LinkedIn one. After dealing with this for more than a week, I decided on posting it here and see if anyone could help.
Context:
- Google SSO is working well, within the same conditions (it's the same app).
- LinkedIn SSO is working well when testing the app locally, but it hangs on getting the accessToken when deployed.
- The process manages to get the authorisation token (previous step into getting the accessToken), but it gets a timeout error when request the accessToken.
See image of the code snippet where the process hangs (line 494, fastapi_sso/sso/base.py):
Any thoughts why this may be happening?
Thanks for your amazing contribution to the community, btw!
Hi @antonionieto! Thanks for posting this, this seems like a pickle, it's weird that it's working for you locally. Could you please also attach the traceback? It would be cool to see more. TimeoutError is quite unexpected, I would like to see if it's a network or transport issue rather than oauth / http.
Hi @tomasvotava, thanks for the quick reply! Sure, here is an screenshot of the traceback. It seems like the LinkedIn acessToken endpoint is not responding at all. Authorisation endpoint is working though, as I checked it out and I am correctly getting the authorisation code.
Thanks for the traceback! httpx
uses a default timeout of 5 seconds to wait for the socket to connect, I cannot imagine why it would take longer than that, but we could tinker with that number. I cannot stop thinking this really has to be some kind of network issue, because you said it works well when run locally.
How do you run your app in Cloud Run? Could that be that e.g. uvicorn has some async issues blocking httpx's requests?
Could you try getting a refresh token locally (you can try simply accessing sso.refresh_token
property after successful call to verify_and_process
) and then exchanging the refresh token for an access token in some simple Cloud Run app? Something like:
import httpx
async def amain():
data = {"grant_type": "refresh_token", "refresh_token": "your-secret-token", "client_id": "your client id", "client_secret": "your client secret"}
async with httpx.AsyncClient() as session:
response = await session.post("https://www.linkedin.com/oauth/v2/accessToken", data=data)
response.raise_for_status()
return response.json()
Running this without uvicorn and any other overhead successfully could point us in the direction. If this fails as well, then I'd really say it's some fishy network issue you should probably either open with Linked or Google.
It actually doesn't matter if you send the refresh token or not, plainly calling await session.post("https://www.linkedin.com/oauth/v2/accessToken")
and checking that there actually was a response should be enough. You'll probably get 400
if you don't send anything else.
I just tried out with a simple HTTP POST, as suggested, and still got the same issue: the LinkedIn server does not respond at all. It just weird, cause the authorisation endpoint works well (also in Cloud Run). This is really confusing :|
Will try to explore other ways and make sure I share the solution (if I find it) with the community. Btw, really appreciate the time you dedicate into this @tomasvotava!
Ouch, that's hard to debug, you could probably try setting up logging to DEBUG
level, maybe httpx
will tell you more that way. Also, try using requests
module instead, I think it uses urllib instead of httpcore
, but that's just guessing.
Feel free to let me know when you know more, I'll be glad to help and it would be awesome to have some resolution for others who may stumble upon this.
Good news! I managed to find the issue and it was, effectively, a networking issue - It turned out Cloud Run was routing all the traffic to an internal VPC and the requests weren't able to reach out the public internet. It was solved by creating a NAT gateway and assigning a static IP address (reference).
The confusing thing was, also, that I was using Google SignIn (leveraging fastapi-sso as well) and it was working well! My assumption is that given it is a Google service, it somehow manages to reach the SSO provider without getting into the public internet (maybe I'm completely wrong).
Anyways, really appreciate the community support here! <3
Feel free to close the issue then :)
Thanks a lot for letting me know! This may help others in the future.