Open utterances-bot opened 3 years ago
Hi,
First: thank you for a wonderful piece of work here. Amazing job.
I come from a C background and I'm learning Python / Flask - and there's a part of your code that has me stumped.
You run this unit test:
def test_encode_access_token(user):
access_token = user.encode_access_token()
assert isinstance(access_token, bytes)
This fails for me, because jwt.encode() returns a str type, not bytes.
Then, in other parts of the code I end up with issues because you use the b'' with strings, and my program crashes.
I checked the jwt docs https://pyjwt.readthedocs.io/en/stable/api.html#jwt.encode which seem to confirm a str type is returned.
Any idea how your test passes?
Thanks so much!
Your test seemed to pass, and I was wondering why?
@rjallbert I guess, in that case, the encoded object is pre decoded with 'utf-8' which then return string instead of bytes.
Just a note that from werkzeug.security import generate_password_hash
is comparable to bcrypt as the default encryption is pbkdf2:sha256
. No need to install bcrypt as Flask ships with Werkzeug.
Aaron, This is a fantastic tutorial. I have a question. How do I connect to two databases at the same time using this tutorial?I know SQLALCHEMY_BINDS but would be great if any suggestion is provided.
First: thank you for a wonderful piece of work here. Amazing job.
Hi @rjallbert , I had this issue too.
FWIW, it appears as though jwt.encode returned a token of type bytes in v2.0.0a1, so perhaps the tutorial was using this version. Unfortunately no requirements.txt
file is attached to the repo, so I can't tell which package versions were used. (which also caused me issues with Flake8, black and click compatibility issues on recent versions)
Code to fix failed test case for invalid user token byte & str error:
def test_decode_access_token_invalid(user): access_token = user.encode_access_token() split = access_token.split(".") payload_base64 = split[1] pad_len = 4 - (len(payload_base64) % 4) payload_base64 += pad_len * "=" payload_str = urlsafe_b64decode(payload_base64).decode("utf-8") payload = json.loads(payload_str) assert not payload["admin"] payload["admin"] = True payload_mod = json.dumps(payload) payload_mod_base64 = urlsafe_b64encode(payload_mod.encode()) split[1] = payload_mod_base64.strip(b"=") split[1] = split[1].decode("utf-8") access_token_mod = ".".join(split) assert not access_token == access_token_mod result = User.decode_access_token(access_token_mod) assert not result.success assert result.error == "Invalid access token. Please log in again."
awesome!
How To: Create a Flask API with JWT-Based Authentication (Part 2) - aaronluna.dev
Part 2 covers the basics of SQLAlchemy, the Flask-SQLAlchemy extension, and the Flask-Migrate extension. The process of creating a new database table to store user information by defining a class and “registering” it with SQLAlchemy is demonstrated. Next, setting up a system that manages changes to a database schema is thoroughly explained and demonstrated. After initializing the database, functions to encode and decode JSON Web Tokens (JWTs) are created. This section concludes with an introduction to pytest fixtures and examples of several test cases that verify the ability to encode/decode JWTs issued by our API.
https://aaronluna.dev/series/flask-api-tutorial/part-2/