0

I was able to work with Firebase JWT and Flask JWT Extended in order to login my users and validate the JWT. To validate the JWT issued by Firebase to my app I had to code the following:

import requests
from cryptography import x509

from app import jwt

@jwt.decode_key_loader
def decode_key_loader(claims, jwt_headers):
    return convert_cert_to_pem(claims['kid'])


def convert_cert_to_pem(kid):
    certificate = get_public_keys(kid)
    # This is transformed because google gives pem key form, it has to be loaded to x509 certificate.
    cert = x509.load_pem_x509_certificate(certificate.encode())
    pub = cert.public_key()
    return pub


def get_public_keys(kid=None):
    # TODO: these certificates rotates so a cache should be implemented
    certificate_url = 'https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com'
    response = requests.get(certificate_url, verify=True)
    return response.json()[kid]

But now I want to add the authentication to my frontend app and I want to use cookies. Following the docs of flask jwt extended I did this login feature:

@app.route("/login", methods=["POST"])
def login():
    email = request.json.get("email")
    password = request.json.get("password")
    user = fb_auth.sign_in_with_email_and_password(email, password)
    id_token = user['idToken']
    # access_token = create_access_token(identity=user)
    response = jsonify({'token': id_token})
    set_access_cookies(response, id_token)
    return jsonify({'token': id_token}), 200

When I try to run that code I get the following error:

Traceback (most recent call last):
  File "/mnt/d/Projects/api/venv/lib/python3.7/site-packages/flask/app.py", line 2528, in wsgi_app
    response = self.full_dispatch_request()
  File "/mnt/d/Projects/api/venv/lib/python3.7/site-packages/flask/app.py", line 1825, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/mnt/d/Projects/api/venv/lib/python3.7/site-packages/flask_cors/extension.py", line 165, in wrapped_function
    return cors_after_request(app.make_response(f(*args, **kwargs)))
  File "/mnt/d/Projects/api/venv/lib/python3.7/site-packages/flask/app.py", line 1823, in full_dispatch_request
    rv = self.dispatch_request()
  File "/mnt/d/Projects/api/venv/lib/python3.7/site-packages/flask/app.py", line 1799, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
  File "/mnt/d/Projects/api/app/controllers/auth.py", line 30, in login
    set_access_cookies(response, id_token)
  File "/mnt/d/Projects/api/venv/lib/python3.7/site-packages/flask_jwt_extended/utils.py", line 310, in set_access_cookies
    value=get_csrf_token(encoded_access_token),
  File "/mnt/d/Projects/api/venv/lib/python3.7/site-packages/flask_jwt_extended/utils.py", line 267, in get_csrf_token
    return token["csrf"]
KeyError: 'csrf'
127.0.0.1 - - [13/Mar/2023 15:44:02] "POST /login HTTP/1.1" 500 -

I guess that this is happening because I am not calling the create_access_token function provided by the Flask JWT Extended package and I don't think I should call it given that I already have my jwt working and being validated correctly. I also tried to call that function passing in the user variable which is a dictionary (checkc the commented line on the login endpoint) but then I got a new error:

RuntimeError: JWT_PRIVATE_KEY must be set to use asymmetric cryptography algorithm "RS256"

I would like to use the JWT issued by the firebase with cookies, but I had no success until now. I'd appreciate it if someone could help me out here. Thanks!

Bruno Casarotti
  • 623
  • 8
  • 23

0 Answers0