Navigation

The fresh token pattern is built into this extension. This pattern is very
simple, you can choose to mark some access tokens as fresh and others as
non-fresh, and use the fresh_jwt_required() decorator
to only allow fresh tokens to access certain endpoints.

This is useful for allowing fresh tokens to do some critical things (such as
update an email address or complete an online purchase), but to deny those
features to non-fresh tokens. Utilizing Fresh tokens in conjunction with
refresh tokens can lead to a more secure site, without creating a bad user
experience by making users constantly re-authenticate.

Here is an example of how you could utilize refresh tokens with the
fresh token pattern:

fromflaskimportFlask,jsonify,requestfromflask_jwt_extendedimport(JWTManager,jwt_required,create_access_token,jwt_refresh_token_required,create_refresh_token,get_jwt_identity,fresh_jwt_required)app=Flask(__name__)app.config['JWT_SECRET_KEY']='super-secret'# Change this!jwt=JWTManager(app)# Standard login endpoint. Will return a fresh access token and# a refresh token@app.route('/login',methods=['POST'])deflogin():username=request.json.get('username',None)password=request.json.get('password',None)ifusername!='test'orpassword!='test':returnjsonify({"msg":"Bad username or password"}),401# create_access_token supports an optional 'fresh' argument,# which marks the token as fresh or non-fresh accordingly.# As we just verified their username and password, we are# going to mark the token as fresh here.ret={'access_token':create_access_token(identity=username,fresh=True),'refresh_token':create_refresh_token(identity=username)}returnjsonify(ret),200# Refresh token endpoint. This will generate a new access token from# the refresh token, but will mark that access token as non-fresh,# as we do not actually verify a password in this endpoint.@app.route('/refresh',methods=['POST'])@jwt_refresh_token_requireddefrefresh():current_user=get_jwt_identity()new_token=create_access_token(identity=current_user,fresh=False)ret={'access_token':new_token}returnjsonify(ret),200# Fresh login endpoint. This is designed to be used if we need to# make a fresh token for a user (by verifying they have the# correct username and password). Unlike the standard login endpoint,# this will only return a new access token, so that we don't keep# generating new refresh tokens, which entirely defeats their point.@app.route('/fresh-login',methods=['POST'])deffresh_login():username=request.json.get('username',None)password=request.json.get('password',None)ifusername!='test'orpassword!='test':returnjsonify({"msg":"Bad username or password"}),401new_token=create_access_token(identity=username,fresh=True)ret={'access_token':new_token}returnjsonify(ret),200# Any valid JWT can access this endpoint@app.route('/protected',methods=['GET'])@jwt_requireddefprotected():username=get_jwt_identity()returnjsonify(logged_in_as=username),200# Only fresh JWTs can access this endpoint@app.route('/protected-fresh',methods=['GET'])@fresh_jwt_requireddefprotected_fresh():username=get_jwt_identity()returnjsonify(fresh_logged_in_as=username),200if__name__=='__main__':app.run()