基于Flask的通用登录注册模块,并代理跳转到目标网址

实现了用户密码的加密,代理跳转到目标网址,不会暴露目标路径,未登录的情况下访问proxy则自动跳转到登录页,使用时需要修改配置项config,登录注册页面背景快速修改,可以实现登录注册模块的快速复用。

1.app.py

from flask import Flask, render_template, request, redirect, url_for, session, Response
import sqlite3
import os
import bcrypt
import requests

app = Flask(__name__)
app.secret_key = os.urandom(24)


# 数据库连接
def get_db():
    conn = sqlite3.connect('users.db')
    return conn


# 创建用户表
def create_user_table():
    conn = get_db()
    c = conn.cursor()
    c.execute('''CREATE TABLE IF NOT EXISTS users
                 (id INTEGER PRIMARY KEY AUTOINCREMENT,
                 username TEXT NOT NULL UNIQUE,
                 password TEXT NOT NULL)''')
    conn.commit()
    conn.close()


create_user_table()

# 配置项
config = {
    "after_login_url": "http://xxxx",  # 修改为目标网址
    "after_register_url": "/login",
    "login_background_image": "static/login_background.jpg",
    "register_background_image": "static/register_background.jpg"
}


# 检查用户是否登录的装饰器
def login_required(func):
    def wrapper(*args, **kwargs):
        if 'username' not in session:
            return redirect(url_for('login'))
        return func(*args, **kwargs)

    wrapper.__name__ = func.__name__
    return wrapper


# 注册页面
@app.route('/register', methods=['GET', 'POST'])
def register():
    error = None
    success = None
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password').encode('utf-8')
        hashed = bcrypt.hashpw(password, bcrypt.gensalt())

        conn = get_db()
        c = conn.cursor()
        try:
            c.execute("INSERT INTO users (username, password) VALUES (?,?)", (username, hashed))
            conn.commit()
            success = "注册成功!请登录。"
        except sqlite3.IntegrityError as e:
            print(f"IntegrityError: {e}")
            error = "用户名已存在,请选择其他用户名。"
        finally:
            conn.close()
    return render_template('register.html', error=error, success=success,
                           background_image=config["register_background_image"])


# 登录页面
@app.route('/login', methods=['GET', 'POST'])
def login():
    error = None
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password').encode('utf-8')
        remember_me = request.form.get('remember_me')

        conn = get_db()
        c = conn.cursor()
        c.execute("SELECT password FROM users WHERE username =?", (username,))
        user = c.fetchone()
        conn.close()

        if user:
            stored_password = user[0]
            if bcrypt.checkpw(password, stored_password):
                session['username'] = username
                if remember_me:
                    session.permanent = True
                return redirect(url_for('proxy'))
        error = "用户名或密码错误。"

    return render_template('login.html', error=error, background_image=config["login_background_image"])


# 注销
@app.route('/logout')
def logout():
    session.pop('username', None)
    return redirect(url_for('login'))


# 代理请求
@app.route('/proxy')
@login_required
def proxy():
    target_url = config["after_login_url"]
    try:
        resp = requests.get(target_url, headers=dict(request.headers))
        excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection']
        headers = [(name, value) for (name, value) in resp.raw.headers.items()
                   if name.lower() not in excluded_headers]
        return Response(resp.content, resp.status_code, headers)
    except requests.RequestException as e:
        return f"请求出错: {str(e)}", 500


# 将根目录设置为跳转到代理路由
@app.route('/')
@login_required
def index():
    return redirect(url_for('proxy'))


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

2.login.html





    
    
    登录
    
    
    



    

登录

{% if error %} {% endif %}

还没有账号?注册

3.register.html





    
    
    注册
    
    
    



    

注册

{% if error %} {% endif %} {% if success %} {% endif %}

已有账号?登录

你可能感兴趣的:(通用网站搭建,flask,python,后端)