Hi, I’m creating a web app using flask, the app has an api and a frontend that uses that api, the authentication system uses a JWT, heres the login code for the api:
@api.route("/login", methods=["POST"])
def api_login():
username = request.json.get("username")
password = request.json.get("password")
# Checks if both a username and a password were submitted
if not (username and password):
return jsonify({"successful": False, "status": "Either a username or a password wasn't submitted", "code": 2}), 400
# Search the user by username
user = db.session.scalars(db.select(User).where(User.username == username)).one()
# Checks that both the username and the password are correct
if user is None:
return jsonify({"successful": False, "status": "Username or password incorrect", "code": 1}), 401
if not check_password_hash(user.password_hash, password):
return jsonify({"successful": False, "status": "Username or password incorrect", "code": 1}), 401
# Create a JWT and returns it
token = create_access_token(identity=username, expires_delta=False)
return jsonify({"successful": True, "jwt": token})
In the frontend, I have an html login page returned by flask with the following code
@users.route("/login")
def login():
return render_template("auth/login.html")
this page sends a request from a form to the api via javascript, now here’s the problem, from what I can gather online the most secure way to store the returned jwt is in an httponly cookie however that means that the javascript code can’t create the cookie. I can see multiple ways to solve this problem but all of them have drawbacks, the first one would be to add, in the flask frontend code, a url to store a jwt in an httponly cookie and then from javascript, call that endpoint, however it feels strange to have a url never directly accessed by the browser in the frontend. I could also put that same code in the api, but that feels even stranger as that endpoint would be specific to the frontend and wouldn’t be used by eg. a mobile app. Finally, I could store the jwt in an unsecure cookie, or localstorage, this is apparently less secure due to the risk of an xss attack but it seems to be the approach of several frontends for lemmy. Is there a better way to store the token that I’m not thinking of, if not which solution would be the best?
Unless there’s a detail in here that I’m missing, I think what you want is to have your POST endpoint set the cookie on the flask side via response.set_cookie.
Then you can write a @login_required decorator to add to your login-gated routes that confirms the JWT is valid and unexpired.
To be clear, the endpoint I should modify is the api login one?

