-
-
Notifications
You must be signed in to change notification settings - Fork 462
Description
I want to use FastAPI as a backend for an app that has sign in with google and no other sign in options. I also want to use jwt authentication for each request. Using OAuth2PasswordBearer
doesn't work for me - the OpenAPI spec is then generated with a whole user/password flow and requires hitting an endpoint.
The authorize button in swagger shows this whole thing, that I don't need, or want.

I just want to provide a Bearer token and be able to use that for authenticated requests. fastapi-users does let us customize. Lets use fastapi.security.HTTPBearer
as the scheme, and build a simple custom transport
# skipping most imports
from fastapi.security import HTTPBearer
class HTTPBearerTransport(Transport):
scheme: HTTPBearer
def __init__(self):
self.scheme = HTTPBearer()
# most everything else the same as OAuth2PasswordBearer
However, this customizability doesn't actually work very well with fastapi-users handling of JWTs.
The scheme/transport returns a HTTPAuthorizationCredentials from fastapi.
But the JWTStrategy in fastapi-users requires a str. There is no way to tell fastapi-users that you need to pull the .credentials
property out of the object returned by the transport.
You then need to write a custom JWTStrategy
class HTTPAuthorizationCredentialsJWTStrategy(JWTStrategy):
async def read_token(
self, token: HTTPAuthorizationCredentials | None, user_manager: UserManager
):
token_str = None
if token is not None:
token_str = token.credentials
return await super().read_token(token_str, user_manager)
def get_jwt_strategy() -> JWTStrategy:
return HTTPAuthorizationCredentialsJWTStrategy(
secret=settings.JWT_SECRET,
lifetime_seconds=3600,
token_audience=["fastapi-users:auth"],
)
All of this actually does work - but it is super unergonomic and it means that the extensibility of using a custom transport and strategy is relatively unstable. I was wondering if you might be open to improving the API here such that either the transport or the jwt strategy allows the client to pass in a way to get the underlying token?