0

I create a client (plain python script) and server (flask app) in Python. I wonder how to perform simple authentication using a access key in Python. Authentication is for scripts - they are not real users (no registration required). The key will be assigned to the script during implementation.

Scenario 1:

  1. Client sends message to server.
  2. Server (flask app) reads token from Authorization header.
  3. Server looks for the token in the database.
  4. If server finds token in database it will authenticate the client.

The access token is explicitly passed to the client before sending messages and the client stores it in an environment variable.

Disadventages:

  • Tokens are not stored as hashes

Scenario 2:

  1. Client sends message to server.
  2. Server (flask app) reads token (jwt) from Authorization header.
  3. Server decodes jwt token to: {'accessKeyId': 'fake_id', 'accessKey': 'fake_key'}
  4. Server looks for the key in database by id.
  5. If server finds row in db and key matches to decoded server will authenticate the client.

Adventages:

  • Keys are stored as hashes

The access token is explicitly passed to the client too. It requires:

  • create {'accessKeyId': 'fake_id', 'accessKey': 'fake_key'} object,
  • hash 'fake_key' (and save to server database),
  • generate jwt token (finally it will passed for client and it will be in environment variable).

Is the 2nd approach correct? How is this implemented in applications where the user gets an access key after registration in web app and can query the api (via REST) if the key is correct - sth like OpenWeatherMaps?

Edit: I found out that I need to implement the KEY API mechanism. Are there any guides on how to do this in Flask/Python?

MartinAg
  • 21
  • 3

1 Answers1

0

This decision is very situation dependent. I've read over your question and personally, I'd go with scenario 1. Unless of course, you don't want the script to know its own key? But that defeats the purpose in some ways because you'd need to refresh that key since JWTs have an expiry value and common practice is to have them short-lived. It seems like scenario 2 just adds unnecessary complexity.

You're still validating the token against the database in both scenarios. Unless you're encrypting the JWT then you'll still be enabling users of that JWT to view that same token. If you want to encrypt it, then go for it...but you've just created an encrypted token-like header which just adds more overhead because instead of just going token to database you're going to JWT -> decrypt -> Token -> database on every request and you'll still need some sort of access token for them to regenerate that JWT.

If you have special claims to give them and want to communicate that via JWT then that's valid, but you'll still need them to be short-lived and they have to refresh them.

tl;dr I'd go with scenario 1, it just seems based on the example to be the better solution in my opinion.

Not sure how much you've looked into JWT's but this may be a good place to start.

Matt Hatcher
  • 663
  • 1
  • 4
  • 17
  • Would you have an idea how to store tokens as hash values ​​in a database on the server side in the scenario 1? I have a table in the database with the columns: token id and token (hashed values here). I read the token sent by the client from the client's request header and I hash it. I wonder how to verify it with the token hashes (which can be a lot) from the table in db? It would be great to have a token id in the client request, which alows me matching single database token and verify it quickly. – MartinAg Jun 07 '22 at 22:03
  • Just to clarify, your plan is to: generate a raw token (to give to the user), hash the token like a password, then store that token? If I'm understanding it correctly, it would be just like storing a user's password and you'd validate it on every request. However, if that's your plan and you use a [hashing recommended by OWASP](https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html) then you might want to look at scenario too because hashing and validation are expensive on CPU and you might want to explore short lived JWT instead. – Matt Hatcher Jun 07 '22 at 22:13
  • Yes, it is. I generate a raw token (to give to the user and it should never expire ), hash the token like a password, then store that token in db. And in this scenario I wonder how to verify the token I get from the user? – MartinAg Jun 07 '22 at 22:25