admin管理员组文章数量:1355670
In my fastapi app, I have an endpoint "/refresh"
which is called automatically from the flutter mobile app when a previous call (with the access token in the header) to a protected endpoint failed because the access token was expired. "/refresh"
is called with the refresh_token in the request body, the endpoint looks like this:
@router.post("/refresh/", response_model=TokenResponse)
async def refresh_token(
refresh_request: RefreshRequest,
supabase: Client = Depends(get_supabase_client),
):
if refresh_request.refresh_token is None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Refresh token is required",
)
try:
print(f"Received refresh token: {refresh_request.refresh_token}")
response = supabase.auth.refresh_session(refresh_request.refresh_token)
if response.session:
print(f"New refresh token: {response.session.refresh_token}")
return TokenResponse(
access_token=response.session.access_token,
refresh_token=response.session.refresh_token,
token_type="bearer",
expires_in=response.session.expires_in,
expires_at=response.session.expires_at or 0,
)
else:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid refresh token",
)
except Exception as e:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail=f"Token refresh failed: {str(e)}",
)
Context: Calling the endpoint "/login"
returns access token and refresh token. While the access token is valid, I can call "/refresh"
and all other protected routes with the access token and it works fine. But as soon as the access token is expired, and I call "/refresh"
with the refresh token, then i get this error:
{
"detail": "Token refresh failed: Invalid Refresh Token: Already Used"
}
This behavior is the same when i test locally with Postman/ Bruno.
EDIT:
When I islotate the issue to a separate python script and set in supabase access token expiration time to 30 seconds:
The script first logs in, then waits 30 seconds, then tries to refresh, then fails ONLY when i pass the refresh token to SUPABASE.auth.refresh_session(token.refresh_token)
. without the token.refresh_token argument it works fine. but this obviously can not work with fastapi or where should supabase then know for which user to refresh the session?
The script:
class TokenResponse(BaseModel):
access_token: str
refresh_token: str
token_type: str
expires_in: int
expires_at: int
def countdown(seconds):
for i in range(seconds, 0, -1):
print(f"{i} seconds remaining")
time.sleep(1)
print("Time's up!")
def login_and_refresh():
SUPABASE = create_client(
SUPABASE_URL,
SUPABASE_KEY,
)
print("Logging in...")
login_response = SUPABASE.auth.sign_in_with_password(
{
"email": "[email protected]",
"password": "super-secret",
}
)
if not login_response.user or not login_response.session:
print("Invalid credentials")
return
print("LOGGED IN!")
token = TokenResponse(
access_token=login_response.session.access_token,
refresh_token=login_response.session.refresh_token,
token_type="bearer",
expires_in=login_response.session.expires_in,
expires_at=login_response.session.expires_at or 0,
)
print("Initial access_token:", token.access_token[:10] + "...")
print("Initial refresh_token:", token.refresh_token[:10] + "...")
# Wait for access token to be close to expiration
countdown(31) # Wait for 31 seconds
print("Attempting to refresh token...")
try:
user = SUPABASE.auth.get_user(token.access_token)
print("user", user)
refresh_response = SUPABASE.auth.refresh_session(token.refresh_token)
if not refresh_response.session:
print("Failed to refresh session: No session returned")
return
new_token = TokenResponse(
access_token=refresh_response.session.access_token,
refresh_token=refresh_response.session.refresh_token,
token_type="bearer",
expires_in=refresh_response.session.expires_in,
expires_at=refresh_response.session.expires_at or 0,
)
print("Token refreshed successfully")
print("New access_token:", new_token.access_token[:10] + "...")
print("New refresh_token:", new_token.refresh_token[:10] + "...")
except Exception as e:
print(f"Error refreshing token: {str(e)}")
if __name__ == "__main__":
login_and_refresh()
What am I doing wrong? How can I return a valid pair of access and refresh token using the old refresh token once the access token is expired?
Thanks for your help!
本文标签:
版权声明:本文标题:authentication - Supabase with fastapi: "Invalid Refresh Token: Already Used" despite the refresh token was ne 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744018435a2576763.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论