Skip to content

Commit 900e83d

Browse files
committedNov 1, 2022
Example Flask with flask-restful and flask-jwt-extended
1 parent 65345ee commit 900e83d

File tree

2 files changed

+21
-22
lines changed

2 files changed

+21
-22
lines changed
 

‎README.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11
# demo-react-flask-mui-auth
2-
Example React app utilizing MaterialUI with Flask JWT-authed API backend.
2+
3+
Example React app utilizing MaterialUI with Flask JWT-authed API backend using flask-restful and flask-jwt-extended.
4+
5+
I am by no means an expert in these technologies - in learning, I found there was many different implementation techniques for both Flask and React when considering how to protect resources - I wanted to demonstrate one methodology I found particularly easy to implement while also providing a decent authentication mechanism for users. Keep in mind I am not paying any mind to 'authorization' in this demo and am considering all users to have the same level of permissions in both the front-end and back-end implementations.
6+
7+

‎backend/app.py

+15-21
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
1-
from flask import Flask, request, jsonify
1+
from flask import Flask, request
22
from pymongo import MongoClient
33
from flask_restful import Resource, Api
44
from bson.json_util import dumps
55
from passlib.hash import sha256_crypt
66
from flask_jwt_extended import create_access_token,create_refresh_token,get_jwt,get_jwt_identity, jwt_required, JWTManager
77
import datetime
8-
import time
8+
99
# py -m flask --app app --debug run
1010

11+
# PyMongo DB/Collection Variable Setup
1112
client = MongoClient()
1213
db = client.example_db
1314
demo_collection = db.demo_collection
1415
user_collection = db.user_collection
1516
token_collection = db.token_collection
1617

1718
app = Flask(__name__, template_folder='templates')
19+
app.config['JWT_SECRET_KEY'] = 'jwt-secret-string-example'
20+
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = datetime.timedelta(minutes=240)
21+
app.config['JWT_REFRESH_TOKEN_EXPIRES'] = datetime.timedelta(days=30)
22+
app.config["INITIAL_USERNAME"] = "user@test.com"
23+
app.config["INITIAL_PASSWORD"] = sha256_crypt.encrypt("initial_password")
24+
25+
api = Api(app)
26+
jwt = JWTManager(app)
1827

1928
# For helping with Same-Origin requests from the React App
2029
@app.after_request
@@ -24,27 +33,19 @@ def after_request(response):
2433
response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS')
2534
return response
2635

27-
api = Api(app)
28-
29-
jwt = JWTManager(app)
30-
app.config['JWT_SECRET_KEY'] = 'jwt-secret-string-example'
31-
app.config['JWT_ACCESS_TOKEN_EXPIRES'] = datetime.timedelta(minutes=240)
32-
app.config['JWT_REFRESH_TOKEN_EXPIRES'] = datetime.timedelta(days=30)
3336

3437
@jwt.token_in_blocklist_loader
3538
def check_if_token_in_blacklist(jwt_header, jwt_payload: dict):
3639
jti = jwt_payload['jti']
3740
return is_jti_blacklisted(jti)
3841

42+
3943
def is_jti_blacklisted(jti):
4044
if db.token_collection.count_documents({"jti": jti}) != 0:
4145
return True
4246
else:
4347
return False
4448

45-
app.config["INITIAL_USERNAME"] = "user@test.com"
46-
app.config["INITIAL_PASSWORD"] = sha256_crypt.encrypt("initial_password")
47-
4849
# Create the Initial User specified in the configuration data
4950
def create_initial_user():
5051
temp_dict = {"email": app.config["INITIAL_USERNAME"], "password": app.config["INITIAL_PASSWORD"]}
@@ -57,27 +58,21 @@ def create_initial_user():
5758
user_collection.update_one(temp_dict, {'$set':temp_dict}, upsert=True)
5859
create_initial_user()
5960

61+
6062
# Verify the initial user was created and password functionality is working as expected
6163
def verify_initial_user():
6264
temp_doc = user_collection.find_one({'email': app.config["INITIAL_USERNAME"]}, {})
6365
if sha256_crypt.verify("change_me", temp_doc['password']):
6466
print("[*] Successfully Verified Initial User")
6567
verify_initial_user()
6668

67-
6869
# REST API Specifications for retrieving and setting scan configurations
69-
class Scan(Resource):
70+
class Demo(Resource):
7071
@jwt_required()
7172
def get(self):
72-
time.sleep(1)
7373
scans = demo_collection.aggregate([{"$project": {'id': '$_id', 'name': 1, 'category': 1, 'test_object': 1, '_id': 0}}, ])
7474
return dumps(scans)
75-
76-
@jwt_required()
77-
def post(self):
78-
data = request.get_json()
79-
return jsonify({'data': data}), 201
80-
api.add_resource(Scan, '/api/demo')
75+
api.add_resource(Demo, '/api/demo')
8176

8277
# REST API Specifications for creating JSON Web Tokens (JWTs)
8378
class Login(Resource):
@@ -148,7 +143,6 @@ class Add_User(Resource):
148143
def post(self):
149144
pass
150145

151-
152146
class RevokedToken:
153147
def __init__(self, ident, jti):
154148
self.id = ident

0 commit comments

Comments
 (0)
Please sign in to comment.