Building Secure Login and Registration Systems with Python

 Building a secure login and registration system with Python involves more than just storing usernames and passwords. Security best practices must be followed to protect user data and prevent common vulnerabilities like SQL injection, password leaks, and session hijacking.


✅ Key Features of a Secure Login System

Secure password storage (hashing, salting)


Input validation and sanitization


Session management


CSRF protection


Rate limiting / brute-force protection


Email verification (optional)


HTTPS (important in production)


πŸ”§ Technologies Used

Python


Flask (micro web framework)


Flask-WTF (form handling + CSRF protection)


Flask-Login (session management)


Flask-Bcrypt (password hashing)


SQLite (for demo, but can use PostgreSQL/MySQL)


SQLAlchemy (ORM)


🧱 Project Structure

cpp

Copy

Edit

secure_auth/

├── app.py

├── models.py

├── forms.py

├── templates/

│   ├── login.html

│   ├── register.html

│   └── dashboard.html

└── requirements.txt

πŸ“„ Step-by-Step Code Breakdown

1. requirements.txt

pgsql

Copy

Edit

Flask

Flask-WTF

Flask-Login

Flask-Bcrypt

Flask-SQLAlchemy

email-validator

Install with:


bash

Copy

Edit

pip install -r requirements.txt

2. app.py

python

Copy

Edit

from flask import Flask, render_template, redirect, url_for, flash, request

from flask_sqlalchemy import SQLAlchemy

from flask_bcrypt import Bcrypt

from flask_login import LoginManager, login_user, login_required, logout_user, UserMixin

from forms import RegistrationForm, LoginForm

from models import User


app = Flask(__name__)

app.config['SECRET_KEY'] = 'your-secure-key'

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'


db = SQLAlchemy(app)

bcrypt = Bcrypt(app)

login_manager = LoginManager(app)

login_manager.login_view = 'login'


@login_manager.user_loader

def load_user(user_id):

    return User.query.get(int(user_id))


@app.route("/register", methods=['GET', 'POST'])

def register():

    form = RegistrationForm()

    if form.validate_on_submit():

        hashed_pw = bcrypt.generate_password_hash(form.password.data).decode('utf-8')

        user = User(username=form.username.data, email=form.email.data, password=hashed_pw)

        db.session.add(user)

        db.session.commit()

        flash('Account created!', 'success')

        return redirect(url_for('login'))

    return render_template('register.html', form=form)


@app.route("/login", methods=['GET', 'POST'])

def login():

    form = LoginForm()

    if form.validate_on_submit():

        user = User.query.filter_by(email=form.email.data).first()

        if user and bcrypt.check_password_hash(user.password, form.password.data):

            login_user(user)

            return redirect(url_for('dashboard'))

        else:

            flash('Login Unsuccessful. Please check credentials.', 'danger')

    return render_template('login.html', form=form)


@app.route("/dashboard")

@login_required

def dashboard():

    return render_template('dashboard.html')


@app.route("/logout")

def logout():

    logout_user()

    return redirect(url_for('login'))


if __name__ == '__main__':

    app.run(debug=True)

3. models.py

python

Copy

Edit

from app import db

from flask_login import UserMixin


class User(db.Model, UserMixin):

    id = db.Column(db.Integer, primary_key=True)

    username = db.Column(db.String(20), unique=True, nullable=False)

    email = db.Column(db.String(120), unique=True, nullable=False)

    password = db.Column(db.String(60), nullable=False)

4. forms.py

python

Copy

Edit

from flask_wtf import FlaskForm

from wtforms import StringField, PasswordField, SubmitField

from wtforms.validators import DataRequired, Length, Email, EqualTo, ValidationError

from models import User


class RegistrationForm(FlaskForm):

    username = StringField('Username', validators=[DataRequired(), Length(min=2, max=20)])

    email = StringField('Email', validators=[DataRequired(), Email()])

    password = PasswordField('Password', validators=[DataRequired()])

    confirm_password = PasswordField('Confirm Password',

                                     validators=[DataRequired(), EqualTo('password')])

    submit = SubmitField('Sign Up')


    def validate_email(self, email):

        user = User.query.filter_by(email=email.data).first()

        if user:

            raise ValidationError('That email is already registered.')


class LoginForm(FlaskForm):

    email = StringField('Email', validators=[DataRequired(), Email()])

    password = PasswordField('Password', validators=[DataRequired()])

    submit = SubmitField('Login')

5. Example HTML Template Snippets

register.html


html

Copy

Edit

<form method="POST">

    {{ form.hidden_tag() }}

    {{ form.username.label }} {{ form.username() }}

    {{ form.email.label }} {{ form.email() }}

    {{ form.password.label }} {{ form.password() }}

    {{ form.confirm_password.label }} {{ form.confirm_password() }}

    {{ form.submit() }}

</form>

πŸ” Security Enhancements

CSRF tokens: Enabled by default via Flask-WTF


Password hashing: Using bcrypt


Session protection: Flask-Login handles it


Email verification: Add token-based email validation (using itsdangerous)


Rate limiting: Add Flask-Limiter


HTTPS in production: Use Flask-Talisman or proxy via nginx


✅ Optional: Create Database

Run this once to create the SQLite DB:


python

Copy

Edit

from app import db

db.create_all()

πŸš€ Want More?

I can extend this example to include:


JWT-based APIs


Google/Facebook OAuth


Docker deployment


Two-factor authentication (2FA)


Password reset via email

Learn Full Stack Python Course in Hyderabad

Read More

Understanding CSRF Protection in Django for Full Stack Python Apps

Full Stack Python: Protecting Your Application from SQL Injection

How to Use JWT (JSON Web Tokens) for API Authentication in Python

Introduction to Python for Full Stack Developers

Visit Our IHUB Talent Training Institute in Hyderabad

Get Directions

Comments

Popular posts from this blog

How to Install and Set Up Selenium in Python (Step-by-Step)

Tosca for API Testing: A Step-by-Step Tutorial

Waits in Playwright: Explicit, Implicit, and Auto