article

Friday, April 14, 2023

Python Flask Authentication Server-Sided Sessions

Python Flask Authentication Server-Sided Sessions

https://flask.palletsprojects.com/en/2.2.x/installation/
 
Create an environment
C:\flask_dev>py -3 -m venv venv

Activate the environment
C:\flask_dev>venv\Scripts\activate

Install Flask
venv C:\flask_dev>pip install Flask

Flask-Bcrypt
Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application.
https://pypi.org/project/Flask-Bcrypt/

(venv) PS C:\flask_dev\flaskreact>pip install Flask-Bcrypt

Flask-Session
Flask-Session is an extension for Flask that adds support for Server-side Session to your application.
https://flask-session.readthedocs.io/en/latest/

(venv) PS C:\flask_dev\flaskreact>pip install Flask-Session

python-dotenv
Python-dotenv reads key-value pairs from a .env file and can set them as environment variables.
https://pypi.org/project/python-dotenv/

(venv) PS C:\flask_dev\flaskreact>pip install python-dotenv

Flask-SQLAlchemy
Flask-SQLAlchemy is an extension for Flask that adds support for SQLAlchemy to your application.
https://flask-sqlalchemy.palletsprojects.com/en/3.0.x/

(venv) PS C:\flask_dev\flaskreact>pip install -U Flask-SQLAlchemy
C:\flask_dev\flaskreact\app.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#C:\flask_dev\flaskreact\app.py
from flask import Flask, request, jsonify, session
from flask_bcrypt import Bcrypt #pip install Flask-Bcrypt = https://pypi.org/project/Flask-Bcrypt/
from flask_session import Session #pip install Flask-Session = https://flask-session.readthedocs.io/en/latest/
 
from dotenv import load_dotenv #pip install python-dotenv = https://pypi.org/project/python-dotenv/
load_dotenv()
 
from models import db, User
from datetime import timedelta
 
app = Flask(__name__)
 
app.config['SESSION_PERMANENT'] = True
app.config['SESSION_TYPE'] = 'filesystem'
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=5)
 
# The maximum number of items the session stores before it starts deleting some, default 500
app.config['SESSION_FILE_THRESHOLD'] = 100 
 
 
app.config['SECRET_KEY'] = 'cairocoders-ednalan'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///flaskdb.db'
 
SQLALCHEMY_TRACK_MODIFICATIONS = False
SQLALCHEMY_ECHO = True
 
bcrypt = Bcrypt(app)
server_session = Session(app)
db.init_app(app)
 
with app.app_context():
    db.create_all()
 
@app.route("/profile")
def profile():
    user_id = session.get("user_id")
 
    if not user_id:
        return jsonify({"error": "Unauthorized Access"}), 401
     
    user = User.query.filter_by(id=user_id).first()
    return jsonify({
        "id": user.id,
        "email": user.email
    })
 
@app.route("/signup", methods=["POST"])
def signup():
    email = request.json["email"]
    password = request.json["password"]
 
    user_exists = User.query.filter_by(email=email).first() is not None
 
    if user_exists:
        return jsonify({"error": "Email already exists"}), 409
 
    hashed_password = bcrypt.generate_password_hash(password)
    new_user = User(email=email, password=hashed_password)
    db.session.add(new_user)
    db.session.commit()
     
    session["user_id"] = new_user.id
 
    return jsonify({
        "id": new_user.id,
        "email": new_user.email
    })
 
@app.route("/login", methods=["POST"])
def login_user():
    email = request.json["email"]
    password = request.json["password"]
 
    user = User.query.filter_by(email=email).first()
 
    if user is None:
        return jsonify({"error": "Unauthorized Access"}), 401
 
    if not bcrypt.check_password_hash(user.password, password):
        return jsonify({"error": "Unauthorized"}), 401
     
    session["user_id"] = user.id
 
    return jsonify({
        "id": user.id,
        "email": user.email
    })
 
@app.route("/logout", methods=["POST"])
def logout_user():
    session.pop("user_id")
    return "200"
 
if __name__ == "__main__":
    app.run(debug=True)
C:\flask_dev\flaskreact\models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#C:\flask_dev\flaskreact\models.py
from flask_sqlalchemy import SQLAlchemy
from uuid import uuid4
 
db = SQLAlchemy()
 
def get_uuid():
    return uuid4().hex
 
class User(db.Model):
    __tablename__ = "users"
    id = db.Column(db.String(11), primary_key=True, unique=True, default=get_uuid)
    email = db.Column(db.String(150), unique=True)
    password = db.Column(db.Text, nullable=False)
Postman
Postman is an API platform for building and using APIs. Postman simplifies each step of the API lifecycle and streamlines collaboration so you can create better APIs—faster.
https://www.postman.com/

run (venv) C:\flask_dev\flaskreact>flask run

Related Post