22# things will generally speedy, and it can be (mostly) persistent by dumping
33# the data to disk (see: https://redis.io/topics/persistence). The drawbacks
44# to using redis is you have a higher chance of encountering data loss (in
5- # this case, 'forgetting' that a token was revoked), due to events like
6- # power outages in between making a change to redis and that change being
7- # dumped for a disk.
5+ # this case, 'forgetting' that a token was revoked), when events like
6+ # power outages occur.
87#
9- # So when does it make sense to use redis for a blacklist? If you are blacklist
10- # every token on logout but doing nothing besides that (not keeping track of
11- # what tokens are blacklisted, not providing the option un-revoke blacklisted
12- # tokens, or view tokens that are currently active for a given user), then redis
13- # is a great choice. Worst case, a few tokens might slip between the cracks in
14- # the case of a power outage or other such event, but 99.999% of the time tokens
15- # will be properly blacklisted, and the security of your application should be
16- # peachy.
8+ # When does it make sense to use redis for a blacklist? If you are blacklisting
9+ # every token on logout, and not doing nothing besides that (such as keeping
10+ # track of what tokens are blacklisted, providing options to un-revoke
11+ # blacklisted tokens, or view tokens that are currently active for a user),
12+ # then redis is a great choice. In the worst case, a few tokens might slip
13+ # between the cracks in the case of a power outage or other such event, but
14+ # 99.99% of the time tokens will be properly blacklisted.
1715#
1816# Redis also has the benefit of supporting an expires time when storing data.
19- # Utilizing this, you will not need to manually prune back down the data
20- # store to keep it from blowing up on you over time. We will show how this
21- # could work in this example.
17+ # Utilizing this, you will not need to manually prune down the stored tokens
18+ # to keep it from blowing up over time. This code includes how to do this.
2219#
23- # If you intend to use some of the other features in your blacklist (tracking
20+ # If you intend to use some other features in your blacklist (tracking
2421# what tokens are currently active, option to revoke or unrevoke specific
25- # tokens, etc), data integrity is probably more important to your app then
26- # raw performance, in which case a sql base solution (such as postgres) is
27- # probably a better fit for your blacklist. Check out the "sql_blacklist.py "
22+ # tokens, etc), data integrity is probably more important to you then
23+ # raw performance. In this case a database solution (such as postgres) is
24+ # probably a better fit for your blacklist. Check out the "database_blacklist "
2825# example for how that might work.
2926import redis
3027from datetime import timedelta
3835app .secret_key = 'ChangeMe!'
3936
4037# Setup the flask-jwt-extended extension. See:
41- # http://flask-jwt-extended.readthedocs.io/en/latest/options.html
4238ACCESS_EXPIRES = timedelta (minutes = 15 )
4339REFRESH_EXPIRES = timedelta (days = 30 )
4440app .config ['JWT_ACCESS_TOKEN_EXPIRES' ] = ACCESS_EXPIRES
5349
5450
5551# Create our function to check if a token has been blacklisted. In this simple
56- # case, we will just store the tokens jti (unique identifier) in the redis
57- # store whenever we create it with a revoked status of False . This function
58- # will grab the revoked status from the store and return it . If a token doesn't
59- # exist in our store, we don't know where it came from (as we are adding newly
60- # created # tokens to our store), so we are going to considered to be a
61- # revoked token for safety purposes. This is obviously optional .
52+ # case, we will just store the tokens jti (unique identifier) in redis
53+ # whenever we create a new token ( with the revoked status being 'false') . This
54+ # function will return the revoked status of a token . If a token doesn't
55+ # exist in this store, we don't know where it came from (as we are adding newly
56+ # created tokens to our store with a revoked status of 'false'). In this case
57+ # we will consider the token to be revoked, for safety purposes .
6258@jwt .token_in_blacklist_loader
63- def check_if_token_in_blacklist (decrypted_token ):
59+ def check_if_token_is_revoked (decrypted_token ):
6460 jti = decrypted_token ['jti' ]
6561 entry = revoked_store .get (jti )
6662 if entry is None :
67- return False
63+ return True
6864 return entry == 'true'
6965
7066
@@ -79,7 +75,7 @@ def login():
7975 access_token = create_access_token (identity = username )
8076 refresh_token = create_refresh_token (identity = username )
8177
82- # Store the tokens in our store with a status of not currently revoked. We
78+ # Store the tokens in redis with a status of not currently revoked. We
8379 # can use the `get_jti()` method to get the unique identifier string for
8480 # each token. We can also set an expires time on these tokens in redis,
8581 # so they will get automatically removed after they expire. We will set
0 commit comments