Flask Training , study and exam guide
1 Introduction to Flask
1.1 What is Flask?
1.2 History and Evolution of Flask
1.3 Flask vs Django
1.4 Setting Up the Development Environment
2 Flask Basics
2.1 Installing Flask
2.2 Creating Your First Flask Application
2.3 Understanding the Flask Application Structure
2.4 Routing in Flask
2.5 Variable Rules in Routing
2.6 HTTP Methods (GET, POST, PUT, DELETE)
3 Templates and Static Files
3.1 Introduction to Jinja2 Templates
3.2 Rendering Templates
3.3 Template Inheritance
3.4 Static Files (CSS, JavaScript, Images)
3.5 Using Bootstrap with Flask
4 Forms and User Input
4.1 Introduction to Flask-WTF
4.2 Creating Forms with Flask-WTF
4.3 Validating User Input
4.4 Handling File Uploads
4.5 Flash Messages
5 Databases with Flask
5.1 Introduction to SQLAlchemy
5.2 Setting Up a Database
5.3 Defining Models
5.4 CRUD Operations with SQLAlchemy
5.5 Relationships in SQLAlchemy
5.6 Migrations with Flask-Migrate
6 Authentication and Authorization
6.1 Introduction to Flask-Login
6.2 User Authentication
6.3 Protecting Routes with Login Required
6.4 User Roles and Permissions
6.5 Password Hashing with Werkzeug
7 RESTful APIs with Flask
7.1 Introduction to RESTful APIs
7.2 Creating a RESTful API with Flask
7.3 Serializing and Deserializing Data
7.4 Handling API Errors
7.5 Authentication for APIs
8 Testing Flask Applications
8.1 Introduction to Unit Testing
8.2 Writing Tests with Flask-Testing
8.3 Testing Routes and Views
8.4 Testing Database Interactions
8.5 Continuous Integration with Flask
9 Deployment and Scaling
9.1 Introduction to Deployment
9.2 Deploying Flask Applications on Heroku
9.3 Deploying Flask Applications on AWS
9.4 Scaling Flask Applications
9.5 Load Balancing and Caching
10 Advanced Topics
10.1 Background Tasks with Celery
10.2 WebSockets with Flask-SocketIO
10.3 Internationalization and Localization
10.4 Custom Error Pages
10.5 Extending Flask with Blueprints
11 Exam Preparation
11.1 Review of Key Concepts
11.2 Practice Questions
11.3 Mock Exams
11.4 Tips for the Exam Day
User Authentication in Flask

User Authentication in Flask

Key Concepts

User Registration

User registration is the process of creating a new user account. This typically involves collecting user information such as username, email, and password. The password is usually hashed before being stored in the database to ensure security.

from flask import Flask, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from werkzeug.security import generate_password_hash

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    password = db.Column(db.String(120), nullable=False)

@app.route('/register', methods=['POST'])
def register():
    username = request.form['username']
    password = request.form['password']
    hashed_password = generate_password_hash(password, method='sha256')
    new_user = User(username=username, password=hashed_password)
    db.session.add(new_user)
    db.session.commit()
    return redirect(url_for('login'))
    

User Login

User login is the process of verifying a user's identity by checking their credentials against those stored in the database. If the credentials match, the user is authenticated and can access protected resources.

from flask import Flask, request, redirect, url_for, session
from werkzeug.security import check_password_hash

app = Flask(__name__)
app.secret_key = 'secret'

@app.route('/login', methods=['POST'])
def login():
    username = request.form['username']
    password = request.form['password']
    user = User.query.filter_by(username=username).first()
    if user and check_password_hash(user.password, password):
        session['user_id'] = user.id
        return redirect(url_for('dashboard'))
    return 'Invalid credentials'
    

Password Hashing

Password hashing is the process of converting a password into a fixed-length string of characters, which is then stored in the database. Hashing is a one-way function, meaning it is computationally infeasible to reverse the process. This ensures that even if the database is compromised, the passwords cannot be easily retrieved.

from werkzeug.security import generate_password_hash, check_password_hash

hashed_password = generate_password_hash('password', method='sha256')
print(hashed_password)

if check_password_hash(hashed_password, 'password'):
    print('Password matches')
else:
    print('Password does not match')
    

Session Management

Session management involves maintaining the state of a user's interaction with the application across multiple requests. In Flask, sessions are used to store user-specific data, such as the user ID, which can be used to authenticate subsequent requests.

from flask import Flask, session

app = Flask(__name__)
app.secret_key = 'secret'

@app.route('/dashboard')
def dashboard():
    if 'user_id' in session:
        return f'Welcome, User {session["user_id"]}'
    return 'Please log in'
    

Role-Based Access Control

Role-Based Access Control (RBAC) is a method of regulating access to resources based on the roles of individual users within an organization. Roles are defined based on job functions, and permissions are assigned to these roles. Users are then assigned roles, which determine their access rights.

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    password = db.Column(db.String(120), nullable=False)
    role = db.Column(db.String(80), nullable=False)

@app.route('/admin')
def admin():
    if 'user_id' in session:
        user = User.query.get(session['user_id'])
        if user.role == 'admin':
            return 'Admin dashboard'
    return 'Access denied'
    

Token-Based Authentication

Token-Based Authentication involves issuing a token to the user upon successful login. This token is then included in the headers of subsequent requests to authenticate the user. Tokens are often used in APIs to provide stateless authentication.

from flask import Flask, request, jsonify
import jwt
import datetime

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'

@app.route('/login', methods=['POST'])
def login():
    username = request.json.get('username')
    password = request.json.get('password')
    user = User.query.filter_by(username=username).first()
    if user and check_password_hash(user.password, password):
        token = jwt.encode({'user_id': user.id, 'exp': datetime.datetime.utcnow() + datetime.timedelta(minutes=30)}, app.config['SECRET_KEY'])
        return jsonify({'token': token.decode('UTF-8')})
    return jsonify({'message': 'Invalid credentials'}), 401

@app.route('/protected')
def protected():
    token = request.headers.get('Authorization')
    if not token:
        return jsonify({'message': 'Token is missing'}), 403
    try:
        data = jwt.decode(token, app.config['SECRET_KEY'])
        current_user = User.query.get(data['user_id'])
    except:
        return jsonify({'message': 'Token is invalid'}), 403
    return jsonify({'message': f'Hello, {current_user.username}'})