Skip to content

Instantly share code, notes, and snippets.

@TotallyNotChase
Last active July 13, 2021 17:33
Show Gist options
  • Save TotallyNotChase/fe0d66318e7f6b56fd2bc0b8972a483c to your computer and use it in GitHub Desktop.
Save TotallyNotChase/fe0d66318e7f6b56fd2bc0b8972a483c to your computer and use it in GitHub Desktop.
flask-jwt-backend example
from flask import Flask, redirect, make_response, render_template
from flask_restful import Api
from flask_jwt_extended import (JWTManager, jwt_required,
jwt_refresh_token_required,
jwt_optional, fresh_jwt_required,
get_raw_jwt, get_jwt_identity,
create_access_token, create_refresh_token,
set_access_cookies, set_refresh_cookies,
unset_jwt_cookies,unset_access_cookies)
from datetime import timedelta
app = Flask(__name__)
app.config['BASE_URL'] = 'http://127.0.0.1:5000' #Running on localhost
app.config['JWT_SECRET_KEY'] = 'super-secret' # Change this!
app.config['JWT_TOKEN_LOCATION'] = ['cookies']
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(seconds = 120)
app.config['JWT_COOKIE_CSRF_PROTECT'] = True
app.config['JWT_CSRF_CHECK_FORM'] = True
jwt = JWTManager(app)
@jwt.unauthorized_loader
def unauthorized_callback(callback):
# No auth header
return redirect(app.config['BASE_URL'] + '/', 302)
@jwt.invalid_token_loader
def invalid_token_callback(callback):
# Invalid Fresh/Non-Fresh Access token in auth header
resp = make_response(redirect(app.config['BASE_URL'] + '/'))
unset_jwt_cookies(resp)
return resp, 302
@jwt.expired_token_loader
def expired_token_callback(callback):
# Expired auth header
resp = make_response(redirect(app.config['BASE_URL'] + '/token/refresh'))
unset_access_cookies(resp)
return resp, 302
@app.route('/token/refresh', methods=['GET'])
@jwt_refresh_token_required
def refresh():
# Refreshing expired Access token
user_id = get_jwt_identity()
access_token = create_access_token(identity=str(user_id))
resp = make_response(redirect(app.config['BASE_URL'] + '/', 302))
set_access_cookies(resp, access_token)
return resp
def assign_access_refresh_tokens(user_id, url):
access_token = create_access_token(identity=str(user_id), fresh = True)
refresh_token = create_refresh_token(identity=str(user_id))
resp = make_response(redirect(url, 302))
set_access_cookies(resp, access_token)
set_refresh_cookies(resp, refresh_token)
return resp
def unset_jwt():
resp = make_response(redirect(app.config['BASE_URL'] + '/', 302))
unset_jwt_cookies(resp)
return resp
@app.route('/account')
@fresh_jwt_required
def account():
username = get_jwt_identity()
return render_template('account.html'), 200
# very important account settings
@app.route('/services', methods=['GET'])
@jwt_required
def services():
username = get_jwt_identity()
return render_template('services.html'), 200
# Not important stuff but still needs to be logged in
@app.route('/')
@jwt_optional
def index():
username = get_jwt_identity() # None if not logged in
return render_template('index.html'), 200
# Accessible to everyone but maybe different to logged in users
@app.route('/login', methods=['POST'])
def login():
# Verify username and password
return assign_access_refresh_tokens('test' , app.config['BASE_URL'] + '/')
@app.route('/logout')
@jwt_required
def logout():
# Revoke Fresh/Non-fresh Access and Refresh tokens
return unset_jwt(), 302

To set up this project locally, follow this project structure:-

flask-jwt-backend-example

|--app/
   |--templates/  
        |--index.html
        |--account.html
        |--services.html
    |--__init__.py
|--app.py
You've reached the account page - fresh jwt verified!
from app import app
if __name__ == "__main__":
app.run()
<!DOCTYPE html>
<html>
<body>
<form action="http://127.0.0.1:5000/login" method="POST">
<button type="submit"> Login </button>
</form>
<form action="http://127.0.0.1:5000/account" method="GET">
<button type="submit"> Account </button>
</form>
<form action="http://127.0.0.1:5000/services" method="GET">
<button type="submit"> Services </button>
</form>
<form action="http://127.0.0.1:5000/logout" method="GET">
<button type="submit"> Logout </button>
</form>
</body>
</html>
You've reached the services page - jwt verified!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment