· 5 years ago · Feb 05, 2021, 08:26 AM
1from flask import Flask, jsonify, request
2
3from flask_jwt_extended import (
4 JWTManager, jwt_required, create_access_token,
5 jwt_refresh_token_required, create_refresh_token,
6 get_jwt_identity, set_access_cookies,
7 set_refresh_cookies, unset_jwt_cookies
8)
9
10# NOTE: This is just a basic example of how to enable cookies. This is
11# vulnerable to CSRF attacks, and should not be used as is. See
12# csrf_protection_with_cookies.py for a more complete example!
13
14
15app = Flask(__name__)
16
17# Configure application to store JWTs in cookies. Whenever you make
18# a request to a protected endpoint, you will need to send in the
19# access or refresh JWT via a cookie.
20app.config['JWT_TOKEN_LOCATION'] = ['cookies']
21
22# Set the cookie paths, so that you are only sending your access token
23# cookie to the access endpoints, and only sending your refresh token
24# to the refresh endpoint. Technically this is optional, but it is in
25# your best interest to not send additional cookies in the request if
26# they aren't needed.
27app.config['JWT_ACCESS_COOKIE_PATH'] = '/api/'
28app.config['JWT_REFRESH_COOKIE_PATH'] = '/token/refresh'
29
30# Disable CSRF protection for this example. In almost every case,
31# this is a bad idea. See examples/csrf_protection_with_cookies.py
32# for how safely store JWTs in cookies
33app.config['JWT_COOKIE_CSRF_PROTECT'] = False
34
35# Set the secret key to sign the JWTs with
36app.config['JWT_SECRET_KEY'] = 'super-secret' # Change this!
37
38jwt = JWTManager(app)
39
40
41# Use the set_access_cookie() and set_refresh_cookie() on a response
42# object to set the JWTs in the response cookies. You can configure
43# the cookie names and other settings via various app.config options
44@app.route('/token/auth', methods=['POST'])
45def login():
46 username = request.json.get('username', None)
47 password = request.json.get('password', None)
48 if username != 'test' or password != 'test':
49 return jsonify({'login': False}), 401
50
51 # Create the tokens we will be sending back to the user
52 access_token = create_access_token(identity=username)
53 refresh_token = create_refresh_token(identity=username)
54
55 # Set the JWT cookies in the response
56 resp = jsonify({'login': True})
57 set_access_cookies(resp, access_token)
58 set_refresh_cookies(resp, refresh_token)
59 return resp, 200
60
61
62# Same thing as login here, except we are only setting a new cookie
63# for the access token.
64@app.route('/token/refresh', methods=['POST'])
65@jwt_refresh_token_required
66def refresh():
67 # Create the new access token
68 current_user = get_jwt_identity()
69 access_token = create_access_token(identity=current_user)
70
71 # Set the JWT access cookie in the response
72 resp = jsonify({'refresh': True})
73 set_access_cookies(resp, access_token)
74 return resp, 200
75
76
77# Because the JWTs are stored in an httponly cookie now, we cannot
78# log the user out by simply deleting the cookie in the frontend.
79# We need the backend to send us a response to delete the cookies
80# in order to logout. unset_jwt_cookies is a helper function to
81# do just that.
82@app.route('/token/remove', methods=['POST'])
83def logout():
84 resp = jsonify({'logout': True})
85 unset_jwt_cookies(resp)
86 return resp, 200
87
88
89# We do not need to make any changes to our protected endpoints. They
90# will all still function the exact same as they do when sending the
91# JWT in via a header instead of a cookie
92@app.route('/api/example', methods=['GET'])
93@jwt_required
94def protected():
95 username = get_jwt_identity()
96 return jsonify({'hello': 'from {}'.format(username)}), 200
97
98
99if __name__ == '__main__':
100 app.run()