-
-
Notifications
You must be signed in to change notification settings - Fork 6.4k
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add OAuth2 refresh token Form dependency in security/oauth2.py #3303
Comments
Note that according to the spec, the refresh request should also be to the same |
I can take a shot at the implementation |
@Jan-Jasek - do you still have plans to work on this feature? |
Hi guys thanks for the work. Is this functionality still in the works? Also, @Jan-Jasek do you need help with it? |
Any update on this feature? This would be a huge improvement to the current implementation. |
Is this still being looked at by anybody? @Jan-Jasek ? I'm willing to take a stab at implementing this if nobody else is. |
@kbernst30 I tried the implementation, but did not like the result, because OAuth2 spec has a single So feel free to take the stab. |
I have integrated the refresh token workflow into the same endpoint. We could just simply change class OAuth2PasswordAndRefreshRequestForm:
"""Modified from fastapi.security.OAuth2PasswordRequestForm"""
def __init__(
self,
grant_type: str = Form(default=None, regex="password|refresh_token"),
username: str = Form(default=""),
password: str = Form(default=""),
refresh_token: str = Form(default=""),
scope: str = Form(default=""),
client_id: str | None = Form(default=None),
client_secret: str | None = Form(default=None),
):
self.grant_type = grant_type
self.username = username
self.password = password
self.refresh_token = refresh_token
self.scopes = scope.split()
self.client_id = client_id
self.client_secret = client_secret And then alter the schemas.Token to return class Token(BaseModel):
access_token: str
refresh_token: str
token_type: str In the login endpoint, implement a refresh token authentication function (which could make use of the access token authentication logic), and make a conditional statement on grant_type. @router.post("/token", response_model=schemas.Token)
async def login_for_tokens(
response: Response,
session: AsyncSession = Depends(get_session),
form_data: OAuth2PasswordAndRefreshRequestForm = Depends(),
):
if form_data.grant_type == "refresh_token":
user = authenticate_user_from_token(
session=session,
token=form_data.refresh_token,
secret_key="REFRESH_SECRET_KEY",
)
else:
user = authenticate_user(session, form_data.username, form_data.password)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect username or password",
headers={"WWW-Authenticate": "Bearer"},
)
return create_tokens_from_user(user=user, response=response) Finally, implementing the def create_tokens_from_user(user: models.User, response: Response) -> dict[str, str]:
jwt_data = {"sub": str(user.id)}
access_token_expires = timedelta(minutes="15")
access_token = create_access_token(
data=jwt_data,
expires_delta=access_token_expires,
)
refresh_token_expires = timedelta(minutes="60")
refresh_token = create_refresh_token(
data=jwt_data,
expires_delta=refresh_token_expires,
)
return {
"access_token": access_token,
"refresh_token": refresh_token,
"token_type": "bearer",
} All the details not mentioned above are well explained in the FastAPI documentation. |
Any update here? |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
First check
Description
security/oauth2.py
already containsOAuth2PasswordRequestForm
, why don't we addOAuth2RerefreshRequestForm
to FastAPI as well? It is also well defined in the OAuth RFC. To implement a complete OAuth2 with FastAPI, token refresh is needed. Also, the docs can be updated with a full example.As the RFC states, the refresh request has to be exactly like this:
The solution you would like
A possible implementation would be:
It is indeed simple, but having it in builtin still saves users some time to look up in the RFC. Also, the tutorial in docs can be more complete.
Additional context
RFC6749 section 6 on refresh token grant
The text was updated successfully, but these errors were encountered: