@@ -79,7 +79,8 @@ endpoint, but can be used to create new access tokens once an old access token h
7979By setting the access tokens to a shorter lifetime (see Options bellow), and utilizing
8080fresh tokenks for critical endpoint (see Fresh Tokens bellow) we can help reduce the
8181damage done if an access token is stolen. Here is an example on how to use them:
82- ```
82+
83+ ``` python
8384from flask import Flask, jsonify, request
8485from flask_jwt_extended import JWTManager, jwt_required, create_access_token, \
8586 jwt_refresh_token_required, create_refresh_token, get_jwt_identity
@@ -135,7 +136,86 @@ to login with their username and passwords all the time. Neat. Now lets look at
135136token freshness to see how we can improve upon this further.
136137
137138### Token Freshness
138- TODO
139+ We have the idea of token freshness built into this system. In a nutshell, you can
140+ choose to mark some access tokens as fresh and others as non-fresh, and a
141+ fresh_jwt_required decorator to only allow fresh tokens to access some views.
142+
143+ This is useful for allowing fresh logins to do some critical things (maybe change
144+ a password, or complete an online purchase), but to deny those features to
145+ non-fresh tokens without verifying their username/password. This still allows your
146+ users to access any of the normal jwt_protected endpoints while using a non-fresh
147+ token. Using these wisely can lead to a more secure site, without creating
148+ unnecessarily bad users experiences by having to re-login all the time.
149+
150+ The provided API gives you the power to use the token freshness however you may
151+ want to. A very natural way to do this would be to mark a token as fresh when they
152+ first login, mark any tokens generated with the refresh token to be not fresh,
153+ and provide one more endpoint for generating new fresh tokens (via re-authing)
154+ without generating a new refresh token to go with it.
155+ ``` python
156+ from flask import Flask, jsonify, request
157+ from flask_jwt_extended import JWTManager, jwt_required, create_access_token, \
158+ jwt_refresh_token_required, create_refresh_token, get_jwt_identity, \
159+ fresh_jwt_required
160+
161+ app = Flask(__name__ )
162+ app.secret_key = ' super-secret' # Change this!
163+ jwt = JWTManager(app)
164+
165+
166+ @app.route (' /login' , methods = [' POST' ])
167+ def login ():
168+ username = request.json.get(' username' , None )
169+ password = request.json.get(' password' , None )
170+ if username != ' test' and password != ' test' :
171+ return jsonify({" msg" : " Bad username or password" }), 401
172+
173+ ret = {
174+ ' access_token' : create_access_token(identity = username, fresh = True ),
175+ ' refresh_token' : create_refresh_token(identity = username)
176+ }
177+ return jsonify(ret), 200
178+
179+
180+ @app.route (' /login' , methods = [' POST' ])
181+ def login ():
182+ username = request.json.get(' username' , None )
183+ password = request.json.get(' password' , None )
184+ if username != ' test' and password != ' test' :
185+ return jsonify({" msg" : " Bad username or password" }), 401
186+
187+ ret = {' access_token' : create_access_token(identity = username, fresh = True )}
188+ return jsonify(ret), 200
189+
190+
191+ @app.route (' /refresh' , methods = [' POST' ])
192+ @jwt_refresh_token_required
193+ def refresh ():
194+ current_user = get_jwt_identity()
195+ ret = {
196+ ' access_token' : create_access_token(identity = current_user, fresh = False )
197+ }
198+ return jsonify(ret), 200
199+
200+
201+ @app.route (' /protected' , methods = [' GET' ])
202+ @jwt_required
203+ def protected ():
204+ username = get_jwt_identity()
205+ return jsonify({' hello' : ' from {} ' .format(username)}), 200
206+
207+
208+ @app.route (' /protected-fresh' , methods = [' GET' ])
209+ @fresh_jwt_required
210+ def protected ():
211+ username = get_jwt_identity()
212+ return jsonify({' hello' : ' from {} ' .format(username)}), 200
213+
214+ if __name__ == ' __main__' :
215+ app.run()
216+ ```
217+ The only real things to note here is the new @fresh_jwt_required decorator, and
218+ the optional 'fresh=' keyword passed to the 'create_access_token' methods.
139219
140220### Changing Default Behaviors
141221TODO
0 commit comments