fastapi-sso
fastapi-sso copied to clipboard
Refreshing token support built in?
Hello,
I am implementing SAP XSUAA Oauth2 via GenericSSO client and it works, good job!
I also receive back a refresh token after successful login
According to docs, refreshing the token involves creating a new request like so:
Refresh Token Grant
If the current access token is expired, a new one can be requested with the [Refresh Token flow](https://docs.cloudfoundry.org/api/uaa/version/74.23.0/index.html#refresh-token).
Make a request:
POST https://[xsuaa.url]/oauth/token
Headers
Accept: application/json
Content-Type: application/x-www-form-urlencoded
client_id=[xsuaa.clientid]
client_secret=[xsuaa.clientsecret]
refresh_token=[refresh_token]
grant_type=refresh_token
Check the response:
{
"access_token": [access_token],
"token_type": "bearer",
"id_token": [...],
"refresh_token": [refresh_token],
"expires_in": [...],
"scope": [...],
"jti": [...]
}
Congratulation, you now have a refreshed access_token.
I would like to know if this support is already built in or do we need to manually do this request?
Many thanks!
I rolled my own implementation, here's the code if anyone is interested.
class SAPXsuaaSSO(SSOBase):
provider = "sap.xsuaa"
scope = settings.DEFAULT_SCOPE
async def get_discovery_document(self) -> DiscoveryDocument:
return {
"authorization_endpoint": f"{settings.XSUAA_API_URL}/oauth/authorize/",
"token_endpoint": f"{settings.XSUAA_API_URL}/oauth/token/",
"userinfo_endpoint": f"{settings.XSUAA_API_URL}/userinfo",
}
async def openid_from_response(self, response: dict, session: Optional[httpx.AsyncClient] = None) -> OpenID:
return OpenIDUser(**response)
async def token_refresh(self, refresh_token: str) -> OpenID:
token_url, headers, body = self.oauth_client.prepare_refresh_token_request(
token_url=await self.token_endpoint,
refresh_token=refresh_token,
scope=self.scope,
)
auth = httpx.BasicAuth(self.client_id, self.client_secret)
async with httpx.AsyncClient() as session:
response = await session.post(token_url, headers=headers, content=body, auth=auth)
content = response.json()
self._refresh_token = content.get("refresh_token")
self.oauth_client.parse_request_body_response(json.dumps(content))
uri, headers, _ = self.oauth_client.add_token(await self.userinfo_endpoint)
response = await session.get(uri, headers=headers)
content = response.json()
return await self.openid_from_response(content, session)
Thanks.
@developer992 Hi and thanks for both the question and the solution! I am sorry I didn't have the time to come up with it before you did.
It's actually a good idea to bake the support for refreshing token in, I'll look into it over the holidays!
Thank you man, happy new year as well :)