Skip to main content

Python-multi-user-OTP-login-QRcode

Introduction

Creating a multi-user OTP (One-Time Password) login system with QR code generation in Python involves several steps. This solution will leverage libraries like pyotp for OTP generation, qrcode for QR code generation, and a simple Flask web application for the user interface and backend. Below is a detailed guide to building such a system.

Step 1: Install Required Libraries

First, ensure you have the required libraries installed:

pip install Flask pyotp qrcode[pil] flask_sqlalchemy

Step 2: Set Up the Flask Application

Create a Flask application with a SQLite database for storing user information and OTP secrets.

from flask import Flask, request, redirect, url_for, render_template, session
from flask_sqlalchemy import SQLAlchemy
import pyotp
import qrcode
import io
from PIL import Image

app = Flask(__name__)
app.config['SECRET_KEY'] = 'your_secret_key'
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)
otp_secret = db.Column(db.String(16), nullable=False)

db.create_all()

Step 3: User Registration with OTP Secret and QR Code Generation

Add a route to register users, generate an OTP secret, and display a QR code for them to scan with their authenticator app.

@app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
username = request.form['username']
user = User.query.filter_by(username=username).first()
if user is not None:
return 'User already exists!'

otp_secret = pyotp.random_base32()
new_user = User(username=username, otp_secret=otp_secret)
db.session.add(new_user)
db.session.commit()

# Generate QR code
otp_uri = pyotp.totp.TOTP(otp_secret).provisioning_uri(name=username, issuer_name="YourApp")
img = qrcode.make(otp_uri)
buffer = io.BytesIO()
img.save(buffer, 'PNG')
buffer.seek(0)

return send_file(buffer, mimetype='image/png')
return render_template('register.html')

Step 4: User Login with OTP Verification

Add a route for users to log in by verifying their OTP.


@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
otp = request.form['otp']
user = User.query.filter_by(username=username).first()
if user is None:
return 'User not found!'

totp = pyotp.TOTP(user.otp_secret)
if totp.verify(otp):
session['username'] = username
return 'Login successful!'
else:
return 'Invalid OTP!'
return render_template('login.html')

Step 5: HTML Templates

Create basic HTML templates for registration and login. Here are simple examples:

templates/register.html


<!DOCTYPE html>
<html>
<head>
<title>Register</title>
</head>
<body>
<h1>Register</h1>
<form method="POST">
Username: <input type="text" name="username" required><br>
<button type="submit">Register</button>
</form>
</body>
</html>

templates/login.html


<!DOCTYPE html>
<html>
<head>
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form method="POST">
Username: <input type="text" name="username" required><br>
OTP: <input type="text" name="otp" required><br>
<button type="submit">Login</button>
</form>
</body>
</html>

Step 6: Running the Application

Run your Flask application:


if __name__ == '__main__':
app.run(debug=True)

Summary

This basic example demonstrates how to create a multi-user OTP login system with QR code generation using Python, Flask, and various libraries. In a production system, you would need to add more features like user authentication, password management, and security improvements. Additionally, consider using environment variables or a more secure method for handling sensitive data like SECRET_KEY.