Mini app authentification avec token jwt
This commit is contained in:
parent
e9efcdb236
commit
941cd1f89e
16
README.md
16
README.md
@ -1,2 +1,18 @@
|
||||
# Appli_demo
|
||||
Petite app utilisant l'authentification avec une génération de token jwt.
|
||||
|
||||
## Installation et prérequis
|
||||
Le projet est codé en Python3 il est donc necessaire d'avoir Python3 d'installer sur sa machine. Pour vérifier si
|
||||
Python3 est bien installer `python3 --version`
|
||||
|
||||
Dans un terminal utiliser `pip install -r requirements.txt` (_de préférence dans un environement
|
||||
virtuel_) afin d'installer les librairies necessaires au bon fonctionnement du projet.
|
||||
|
||||
## Lancement du projet
|
||||
Ensuite ouvrez deux terminal et placer vous à la racine du projet.
|
||||
|
||||
Dans le premier taper `flask run` afin de lancer le serveur web.
|
||||
|
||||
Et dans l'autre `python3 requetes.py` afin de lancer une batterie de requête pour vérifier le bon
|
||||
fonctionnement du projet.
|
||||
|
||||
|
146
app.py
Normal file
146
app.py
Normal file
@ -0,0 +1,146 @@
|
||||
from flask import Flask, request, jsonify, make_response, session, render_template, abort
|
||||
from flask_restful import Api, Resource
|
||||
import jwt
|
||||
from datetime import datetime, timedelta
|
||||
from functools import wraps
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
app.config['SECRET_KEY'] = 'secret'
|
||||
|
||||
api = Api(app)
|
||||
|
||||
classes = {'1':
|
||||
{
|
||||
'nom': 'A1',
|
||||
'nombre_eleve': '15',
|
||||
'eleves': {
|
||||
'1': ['Mariue', 'Julien', '12'],
|
||||
'2': ['Koene', 'Morice', '13'],
|
||||
'3': ['Moatir', 'Pierre', '12'],
|
||||
'4': ['Poiti', 'Marc', '12'],
|
||||
'5': ['Areop', 'Tome', '12'],
|
||||
'6': ['Cenois', 'Louis', '13'],
|
||||
'7': ['Quotine', 'Maxime', '12'],
|
||||
'8': ['Reval', 'Adrien', '12'],
|
||||
'9': ['Fonduri', 'Juliette', '11'],
|
||||
'10': ['Graconti', 'Marie', '12'],
|
||||
'11': ['Henvio', 'Louise', '12'],
|
||||
'12': ['Kenano', 'Bertran', '14'],
|
||||
'13': ['Vertille', 'Jean-Pierre', '12'],
|
||||
'14': ['Provern', 'Jean', '14'],
|
||||
'15': ['Secinoi', 'Celine', '12'],
|
||||
}
|
||||
},
|
||||
'2':
|
||||
{
|
||||
'nom': 'A2',
|
||||
'nombre_eleve': '5',
|
||||
'eleves': {
|
||||
'1': ['Benar', 'Leo', '15'],
|
||||
'2': ['Grovin', 'Benois', '16'],
|
||||
'3': ['Xeroi', 'Amelie', '15'],
|
||||
'4': ['Amonie', 'Julien', '14'],
|
||||
'5': ['Surois', 'Camille', '15']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def token_required(func):
|
||||
@wraps(func)
|
||||
def decorated(*args, **kwargs):
|
||||
|
||||
token = None
|
||||
if 'token' in request.headers:
|
||||
token = request.headers['token']
|
||||
|
||||
if not token:
|
||||
return jsonify({'Alert!': 'Pas de Token!'})
|
||||
# abort(403, 'pas de token')
|
||||
try:
|
||||
payload = jwt.decode(token, app.config['SECRET_KEY'])
|
||||
except:
|
||||
# abort(403, 'token invalid')
|
||||
return make_response(jsonify({'Alert!': 'Token invalid!'}))
|
||||
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return decorated
|
||||
|
||||
|
||||
@app.route('/')
|
||||
def home():
|
||||
if not session.get('logged_in'):
|
||||
return render_template('login.html')
|
||||
else:
|
||||
return 'Déjà connecté'
|
||||
|
||||
|
||||
@app.route('/public')
|
||||
def public():
|
||||
return 'Vous êtes bien sur la page public !'
|
||||
|
||||
|
||||
@app.route('/auth', methods=['GET'])
|
||||
@token_required
|
||||
def auth():
|
||||
return 'Vous êtes bien sur la page auth !'
|
||||
|
||||
|
||||
@app.route('/login', methods=['POST'])
|
||||
def login():
|
||||
if request.form['username'] and request.form['password'] == '123':
|
||||
session['logged_in'] = True
|
||||
token = jwt.encode({
|
||||
'user': 0
|
||||
# 'expiration': str(datetime.utcnow() + timedelta(seconds=30))
|
||||
},
|
||||
app.config['SECRET_KEY'], algorithm="HS256")
|
||||
return jsonify({'token': token.decode('utf-8')})
|
||||
else:
|
||||
return make_response('Unable to verify', 403, {'WWW-Authenticate': 'Basic realm:"Authentication Failed!'})
|
||||
|
||||
|
||||
class Classes(Resource):
|
||||
@token_required
|
||||
def get(self):
|
||||
return classes
|
||||
|
||||
@token_required
|
||||
def post(self):
|
||||
return classes
|
||||
|
||||
|
||||
api.add_resource(Classes, "/classes")
|
||||
|
||||
|
||||
class Classe(Resource):
|
||||
@token_required
|
||||
def get(self, id_classe):
|
||||
return classes[id_classe]
|
||||
|
||||
@token_required
|
||||
def post(self, id_classe):
|
||||
return classes[id_classe]
|
||||
|
||||
|
||||
api.add_resource(Classe, "/classes/<string:id_classe>")
|
||||
|
||||
|
||||
class Eleve(Resource):
|
||||
@token_required
|
||||
def get(self, id_classe, id_eleve):
|
||||
return classes[id_classe]['eleves'][id_eleve]
|
||||
|
||||
@token_required
|
||||
def post(self, id_classe, id_eleve):
|
||||
return classes[id_classe]['eleves'][id_eleve]
|
||||
|
||||
|
||||
api.add_resource(Eleve, "/<string:id_classe>/<string:id_eleve>")
|
||||
|
||||
|
||||
@app.route("/reset")
|
||||
def reset():
|
||||
session.clear()
|
35
model/data.py
Normal file
35
model/data.py
Normal file
@ -0,0 +1,35 @@
|
||||
# data = {'1':
|
||||
# {
|
||||
# 'nom': 'A1',
|
||||
# 'nombre_eleve': '15',
|
||||
# 'eleves': {
|
||||
# '1': ['Mariue', 'Julien', '12'],
|
||||
# '2': ['Koene', 'Morice', '13'],
|
||||
# '3': ['Moatir', 'Pierre', '12'],
|
||||
# '4': ['Poiti', 'Marc', '12'],
|
||||
# '5': ['Areop', 'Tome', '12'],
|
||||
# '6': ['Cenois', 'Louis', '13'],
|
||||
# '7': ['Quotine', 'Maxime', '12'],
|
||||
# '8': ['Reval', 'Adrien', '12'],
|
||||
# '9': ['Fonduri', 'Juliette', '11'],
|
||||
# '10': ['Graconti', 'Marie', '12'],
|
||||
# '11': ['Henvio', 'Louise', '12'],
|
||||
# '12': ['Kenano', 'Bertran', '14'],
|
||||
# '13': ['Vertille', 'Jean-Pierre', '12'],
|
||||
# '14': ['Provern', 'Jean', '14'],
|
||||
# '15': ['Secinoi', 'Celine', '12'],
|
||||
# }
|
||||
# },
|
||||
# '2':
|
||||
# {
|
||||
# 'nom': 'A2',
|
||||
# 'nombre_eleve': '5',
|
||||
# 'eleve': {
|
||||
# '1': ['Benar', 'Leo', '15'],
|
||||
# '2': ['Grovin', 'Benois', '16'],
|
||||
# '3': ['Xeroi', 'Amelie', '15'],
|
||||
# '4': ['Amonie', 'Julien', '14'],
|
||||
# '5': ['Surois', 'Camille', '15']
|
||||
# }
|
||||
# }
|
||||
# }
|
60
requetes.py
Normal file
60
requetes.py
Normal file
@ -0,0 +1,60 @@
|
||||
import requests
|
||||
|
||||
BASE = "http://127.0.0.1:5000/"
|
||||
|
||||
login = requests.post(BASE + 'login', {'username': 'leo', 'password': '123'})
|
||||
|
||||
token = login.json()['token']
|
||||
|
||||
print('Génération du token par une authentification correct: ')
|
||||
print(token)
|
||||
print("\n")
|
||||
|
||||
HEADERS = {"Authorization": f"Bearer {token}", 'token': token}
|
||||
|
||||
public = requests.get(BASE + "public")
|
||||
print('Accès à la page public qui ne nécessite pas de token: ')
|
||||
print(public.text)
|
||||
print("\n")
|
||||
|
||||
auth = requests.get(BASE + 'auth', headers=HEADERS)
|
||||
print('Accès à la page auth qui nécessite un token valide: ')
|
||||
print(auth.text)
|
||||
print("\n")
|
||||
|
||||
classes = requests.get(BASE + "classes", headers=HEADERS)
|
||||
print("Les classes : ")
|
||||
print(classes.json())
|
||||
print("\n")
|
||||
|
||||
classes1 = requests.get(BASE + "classes/1", headers=HEADERS)
|
||||
print("La classe 1 : ")
|
||||
print(classes1.json())
|
||||
print("\n")
|
||||
|
||||
eleve = requests.get(BASE + "2/5", headers=HEADERS)
|
||||
print("L'eleve 5 de la classe 2 : ")
|
||||
print(eleve.json())
|
||||
print("\n")
|
||||
|
||||
requests.get(BASE + 'reset')
|
||||
print('Reset de la session pour supprimer le token...')
|
||||
|
||||
login2 = requests.post(BASE + 'login', {'username': 'leo', 'password': 'azerty'})
|
||||
|
||||
print('Login avec un password qui ne générera pas de token... ')
|
||||
print("\n")
|
||||
|
||||
public2 = requests.get(BASE + "public")
|
||||
print('Accès à la page public qui ne nécessite pas de token: ')
|
||||
print(public2.text)
|
||||
print("\n")
|
||||
|
||||
auth2 = requests.get(BASE + 'auth')
|
||||
print('Accès à la page auth qui nécessite un token valide: ')
|
||||
print(auth2.json())
|
||||
print("\n")
|
||||
|
||||
|
||||
|
||||
|
44
requirements.txt
Normal file
44
requirements.txt
Normal file
@ -0,0 +1,44 @@
|
||||
aniso8601==9.0.1
|
||||
anyio==3.3.4
|
||||
api==0.0.7
|
||||
attrs==21.2.0
|
||||
auth==0.5.3
|
||||
blinker==1.4
|
||||
certifi==2021.10.8
|
||||
charset-normalizer==2.0.7
|
||||
click==8.0.3
|
||||
dnspython==2.1.0
|
||||
eventlet==0.32.0
|
||||
falcon==3.0.1
|
||||
fastapi==0.70.0
|
||||
Flask==2.0.2
|
||||
Flask-HTTPAuth==4.5.0
|
||||
Flask-JWT==0.3.2
|
||||
Flask-RESTful==0.3.9
|
||||
greenlet==1.1.2
|
||||
gunicorn==20.1.0
|
||||
idna==3.3
|
||||
itsdangerous==2.0.1
|
||||
Jinja2==3.0.2
|
||||
JsonForm==0.0.2
|
||||
jsonschema==4.1.2
|
||||
JsonSir==0.0.2
|
||||
MarkupSafe==2.0.1
|
||||
mongoengine==0.23.1
|
||||
nose==1.3.7
|
||||
pydantic==1.8.2
|
||||
PyJWT==1.4.2
|
||||
pymongo==3.12.1
|
||||
pyrsistent==0.18.0
|
||||
python-dotenv==0.19.1
|
||||
Python-EasyConfig==0.1.7
|
||||
pytz==2021.3
|
||||
PyYAML==6.0
|
||||
requests==2.26.0
|
||||
Resource==0.2.1
|
||||
six==1.16.0
|
||||
sniffio==1.2.0
|
||||
starlette==0.16.0
|
||||
typing-extensions==3.10.0.2
|
||||
urllib3==1.26.7
|
||||
Werkzeug==2.0.2
|
12
templates/base.html
Normal file
12
templates/base.html
Normal file
@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>{{ title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Mini-App classe</h1>
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
12
templates/login.html
Normal file
12
templates/login.html
Normal file
@ -0,0 +1,12 @@
|
||||
{% extends 'base.html' %}
|
||||
{% block content %}
|
||||
<form action="{{ url_for('login') }}" method="POST">
|
||||
<label for="username">username</label>
|
||||
<input type="text" name="username" placeholder="Username"> <br><br>
|
||||
|
||||
<label for="password">password</label>
|
||||
<input type="password" name="password" placeholder="Password"> <br><br>
|
||||
|
||||
<input type="submit" value="Login">
|
||||
</form>
|
||||
{% endblock %}
|
Loading…
Reference in New Issue
Block a user