杰瑞科技汇

python loginhandler

Of course! A "Login Handler" is a fundamental component in most web applications. It's responsible for managing the entire authentication process: receiving user credentials, verifying them against a database, creating a session, and handling errors.

python loginhandler-图1
(图片来源网络,侵删)

I'll provide you with a comprehensive guide, starting with a simple, self-contained example and then moving to a more robust, production-ready version using a popular framework.


The Simplest Possible Login Handler (No Framework)

This example uses Python's built-in http.server and sqlite3. It's great for understanding the core logic without the complexity of a framework.

Key Concepts:

  • Password Hashing: Never store passwords in plain text! We'll use bcrypt to securely hash passwords.
  • Sessions: We'll use a simple dictionary to simulate logged-in users. In a real app, you'd use a secure session library.
  • Form Handling: The server will serve an HTML form and then process its POST request.

Step 1: Install Necessary Libraries

pip install bcrypt

Step 2: The Python Code (login_server.py)

This single file contains the server logic, database setup, and HTML.

python loginhandler-图2
(图片来源网络,侵删)
import http.server
import socketserver
import sqlite3
import bcrypt
from urllib.parse import parse_qs, urlparse
# --- Database Setup ---
def setup_database():
    conn = sqlite3.connect('users.db')
    cursor = conn.cursor()
    # Create a users table if it doesn't exist
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            username TEXT UNIQUE NOT NULL,
            password_hash TEXT NOT NULL
        )
    ''')
    # Add a default user for testing (hashed password for 'password123')
    try:
        hashed_pw = bcrypt.hashpw('password123'.encode('utf-8'), bcrypt.gensalt())
        cursor.execute("INSERT INTO users (username, password_hash) VALUES (?, ?)", ('admin', hashed_pw))
        conn.commit()
    except sqlite3.IntegrityError:
        # User 'admin' already exists, which is fine
        pass
    conn.close()
# --- Login Handler Logic ---
class LoginHandler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        # Serve the login page for GET requests
        if self.path == '/':
            self.send_response(200)
            self.send_header('Content-type', 'text/html')
            self.end_headers()
            # Simple HTML form
            html = """
            <!DOCTYPE html>
            <html>
            <head>
                <title>Login Page</title>
            </head>
            <body>
                <h1>Login</h1>
                <form action="/login" method="post">
                    Username: <input type="text" name="username"><br>
                    Password: <input type="password" name="password"><br>
                    <input type="submit" value="Login">
                </form>
            </body>
            </html>
            """
            self.wfile.write(html.encode('utf-8'))
        else:
            super().do_GET()
    def do_POST(self):
        if self.path == '/login':
            # Read the form data
            content_length = int(self.headers['Content-Length'])
            post_data = self.rfile.read(content_length)
            parsed_data = parse_qs(post_data.decode('utf-8'))
            username = parsed_data.get('username', [None])[0]
            password = parsed_data.get('password', [None])[0]
            if not username or not password:
                self.send_error(400, "Username and password are required.")
                return
            # Verify credentials against the database
            conn = sqlite3.connect('users.db')
            cursor = conn.cursor()
            cursor.execute("SELECT password_hash FROM users WHERE username = ?", (username,))
            result = cursor.fetchone()
            conn.close()
            if result and bcrypt.checkpw(password.encode('utf-8'), result[0].encode('utf-8')):
                # Successful login!
                self.send_response(302) # Redirect
                self.send_header('Location', '/welcome')
                # In a real app, you would set a secure, HttpOnly cookie here for the session
                self.end_headers()
                print(f"User '{username}' logged in successfully.")
            else:
                # Failed login
                self.send_response(401)
                self.send_header('Content-type', 'text/html')
                self.end_headers()
                html = f"""
                <h1>Login Failed</h1>
                <p>Invalid username or password.</p>
                <a href="/">Try Again</a>
                """
                self.wfile.write(html.encode('utf-8'))
        else:
            self.send_error(404, "Not Found")
# --- Main Execution ---
if __name__ == "__main__":
    setup_database()
    PORT = 8000
    Handler = LoginHandler
    with socketserver.TCPServer(("", PORT), Handler) as httpd:
        print(f"Server running at http://localhost:{PORT}")
        try:
            httpd.serve_forever()
        except KeyboardInterrupt:
            print("\nServer stopped.")
            httpd.server_close()

Step 3: How to Run It

  1. Save the code as login_server.py.
  2. Run it from your terminal: python login_server.py
  3. Open your web browser and go to http://localhost:8000.
  4. Try logging in with:
    • Username: admin
    • Password: password123
  5. Try with incorrect credentials to see the failure message.

A More Robust & Real-World Example (with Flask)

For any real application, you should use a web framework like Flask or Django. They handle routing, sessions, security, and templating much more cleanly.

This example uses:

  • Flask: The web framework.
  • Flask-SQLAlchemy: To interact with the database easily.
  • Flask-Login: To manage user sessions (logging in, logging out, remembering users).
  • Werkzeug: For password hashing (it's a dependency of Flask).

Step 1: Project Setup

# Create a project folder and a virtual environment
mkdir flask_login_app
cd flask_login_app
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate
# Install libraries
pip install Flask Flask-SQLAlchemy Flask-Login

Step 2: Project Structure

/flask_login_app
|-- venv/
|-- app.py              # Main application file
|-- templates/
|   |-- base.html       # Base template with navigation
|   |-- login.html      # Login form
|   |-- home.html       # Welcome page for logged-in users
|   |-- signup.html     # User registration form

Step 3: The Code (app.py)

from flask import Flask, render_template, redirect, url_for, flash, request
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
from werkzeug.security import generate_password_hash, check_password_hash
# --- App and Database Configuration ---
app = Flask(__name__)
# A secret key is needed for session management
app.config['SECRET_KEY'] = 'a-very-secret-key-that-you-should-change'
# Configure the SQLite database
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///users.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login' # Redirect to login page if user is not authenticated
# --- Database Models ---
# UserMixin provides default implementations for the methods that Flask-Login expects user objects to have.
class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(100), unique=True, nullable=False)
    password_hash = db.Column(db.String(200), nullable=False)
    def set_password(self, password):
        self.password_hash = generate_password_hash(password)
    def check_password(self, password):
        return check_password_hash(self.password_hash, password)
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))
# --- Routes ---
@app.route('/')
def home():
    return render_template('home.html', name=current_user.username if current_user.is_authenticated else "Guest")
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        user = User.query.filter_by(username=username).first()
        # Check if user exists and if the password is correct
        if user and user.check_password(password):
            login_user(user) # This creates the user session
            next_page = request.args.get('next')
            # Redirect to the next page if it exists, otherwise go to home
            return redirect(next_page) if next_page else redirect(url_for('dashboard'))
        else:
            flash('Login Unsuccessful. Please check username and password', 'danger')
    return render_template('login.html')
@app.route('/signup', methods=['GET', 'POST'])
def signup():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        # Check if user already exists
        if User.query.filter_by(username=username).first():
            flash('Username already exists. Please choose a different one.', 'warning')
            return redirect(url_for('signup'))
        new_user = User(username=username)
        new_user.set_password(password)
        db.session.add(new_user)
        db.session.commit()
        flash('Your account has been created! You are now able to log in.', 'success')
        return redirect(url_for('login'))
    return render_template('signup.html')
@app.route('/dashboard')
@login_required # This decorator ensures only logged-in users can access this route
def dashboard():
    return render_template('dashboard.html', name=current_user.username)
@app.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('home'))
# --- Main Execution ---
if __name__ == "__main__":
    with app.app_context():
        db.create_all() # Create database tables if they don't exist
    app.run(debug=True)

Step 4: The HTML Templates

templates/base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">{% block title %}My App{% endblock %}</title>
    <style>
        body { font-family: sans-serif; margin: 2em; }
        nav { margin-bottom: 2em; }
        .flash { padding: 1em; background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
    </style>
</head>
<body>
    <nav>
        <a href="{{ url_for('home') }}">Home</a> |
        {% if current_user.is_authenticated %}
            <span>Hello, {{ current_user.username }}!</span> |
            <a href="{{ url_for('logout') }}">Logout</a>
        {% else %}
            <a href="{{ url_for('login') }}">Login</a> |
            <a href="{{ url_for('signup') }}">Sign Up</a>
        {% endif %}
    </nav>
    {% with messages = get_flashed_messages(with_categories=true) %}
        {% if messages %}
            {% for category, message in messages %}
                <div class="flash">{{ message }}</div>
            {% endfor %}
        {% endif %}
    {% endwith %}
    <hr>
    {% block content %}{% endblock %}
</body>
</html>

templates/login.html

python loginhandler-图3
(图片来源网络,侵删)
{% extends "base.html" %}
{% block title %}Login{% endblock %}
{% block content %}
    <h1>Login</h1>
    <form method="post">
        <label for="username">Username:</label><br>
        <input type="text" id="username" name="username" required><br><br>
        <label for="password">Password:</label><br>
        <input type="password" id="password" name="password" required><br><br>
        <input type="submit" value="Login">
    </form>
{% endblock %}

templates/signup.html

{% extends "base.html" %}
{% block title %}Sign Up{% endblock %}
{% block content %}
    <h1>Create an Account</h1>
    <form method="post">
        <label for="username">Username:</label><br>
        <input type="text" id="username" name="username" required><br><br>
        <label for="password">Password:</label><br>
        <input type="password" id="password" name="password" required><br><br>
        <input type="submit" value="Sign Up">
    </form>
{% endblock %}

templates/home.html

{% extends "base.html" %}
{% block title %}Home{% endblock %}
{% block content %}
    <h1>Welcome, {{ name }}!</h1>
    <p>This is the home page.</p>
{% endblock %}

templates/dashboard.html

{% extends "base.html" %}
{% block title %}Dashboard{% endblock %}
{% block content %}
    <h1>Dashboard</h1>
    <p>Welcome to your private dashboard, {{ name }}!</p>
    <p>This page is protected and only visible to logged-in users.</p>
{% endblock %}

Step 5: How to Run the Flask App

  1. Make sure your virtual environment is active.
  2. Run the app: flask run
  3. Open your browser to http://localhost:5000.
  4. You can now sign up for a new account, log in, and see how you're redirected to the protected dashboard. Logging out will take you back to the home page.
分享:
扫描分享到社交APP
上一篇
下一篇