FastAPI, decode JWT id_token returned from Authlib OAuth with Google

202 Views Asked by At

I'm making an API in FastAPI and I want to implement Google Auth, Im using Authlib for that.

I think is important to say that I'M NOT USING TEMPLATES OR SOME KIND OF SSR, my frontend is completely separated from the API.

I have already achieved making a successfull login with Google and redirecting it to an endpoint of my backend, I also save user info in session and the "id_token", this is the endpoint code:

async def auth(request: Request):
try:
    token = await oauth.google.authorize_access_token(request)
except OAuthError as error:
    return RedirectResponse(url='redirect to frontend login page')

user = token.get("userinfo")
jwt_token = token.get("id_token")

if user:
    request.session['user'] = dict(user)
    request.session["token"] = jwt_token

response = RedirectResponse(url="redirect to frontend homepage")
response.set_cookie("token", jwt_token)
return response

That "jwt_token" is the same as "id_token". Now, I'm making a function for protecting my routes, in this function im getting a token from frontend, validating is the same token that one from the current session and decode it to access the info.

But the problem is: What the hell is the secret key for decoding this? I tried a lot of things, all of them pretty dumb. But for now I'm just checking that is the same token:

app = FastAPI()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")

# Necessary to save temporary code & state in session, can be access via "request.session"
app.add_middleware(SessionMiddleware, secret_key="from .env file")

oauth = OAuth()
oauth.register(
    name="google",
    server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
    client_id=CLIENT_ID,
    client_secret=CLIENT_SECRET,
    client_kwargs={
        'scope': 'openid email profile'
    }
)


# Dependency to get the current user
async def get_session_user(request: Request, token: str = Depends(oauth2_scheme)):
    server_token = request.session["token"]

    if token != server_token:
        raise HTTPException(status_code=401, detail="Tokens do not match")

    user = request.session["user"]
    return user


@app.get("/")
async def test_auth(session_user: dict = Security(get_session_user)):
    # Your endpoint logic here
    return {"message": "This is a protected endpoint"}

IN SHORT, how can I decode the the id_token so I can access info, check token expiration time for adding some extra security for my App?

1

There are 1 best solutions below

1
bone2 On

im looking to do the exact same thing . I think when users log in you should check to see if they exist in your database and if they dont write them in and then create your own jwt schema for them. Then you embed your own token in the cookies of the front end. then you will be able to decrypt the token with your key. I am not sure if this is best practice or defeating the point of google oauth but let me know your thoughts.