User Authentication in Flask
Key Concepts
- User Registration
- User Login
- Password Hashing
- Session Management
- Role-Based Access Control
- Token-Based Authentication
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}'})