当前位置: 首页 > news >正文

实验五-Flask的简易登录系统

一、实验目的和任务

1.掌握Flask框架的基本使用方法
2.理解Web应用的会话管理机制
3.实现用户认证系统的基本功能
4.学习模板继承和表单处理技术
要求:请将思考题的答案写在实验报告中

二、实验内容

1.基础环境搭建:创建项目目录结构、安装必要依赖包
2.核心功能实现:用户注册(用户名、密码)、用户登录验证、会话状态管理、用户退出功能
3.前端界面开发:基础模板设计、注册/登录表单实现
4.系统测试验证:注册新用户测试、登录功能测试、会话保持测试

三、实验步骤

1. 项目结构

/flask_auth_system
    ├── app.py
    ├── templates/
        ├── base.html
        ├── index.html
        ├── login.html
        └── register.html

2. app.py(主程序)

from flask import Flask, render_template, request, redirect, url_for, session, flashapp = Flask(__name__)
app.secret_key = '1220911101_fyt_secret_key'# 模拟用户数据库
users = {'admin': 'admin123'  # 预置测试用户
}@app.route('/')
def home():if 'username' in session:return render_template('index.html', username=session['username'])return redirect(url_for('login'))@app.route('/register', methods=['GET', 'POST'])
def register():if request.method == 'POST':username = request.form['username']password = request.form['password']if username in users:flash('用户名已存在')else:users[username] = passwordflash('注册成功,请登录')return redirect(url_for('login'))return render_template('register.html')@app.route('/login', methods=['GET', 'POST'])
def login():if request.method == 'POST':username = request.form['username']password = request.form['password']if username in users and users[username] == password:session['username'] = usernameflash('登录成功')return redirect(url_for('home'))flash('用户名或密码错误')return render_template('login.html')@app.route('/logout')
def logout():session.pop('username', None)flash('您已成功退出')return redirect(url_for('home'))if __name__ == '__main__':app.run(debug=True)

3. templates/base.html(基础模板)

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>{% block title %}1220911101 符亚通 - Flask登录系统{% endblock %}</title><style>body {font-family: Arial, sans-serif;line-height: 1.6;margin: 0;padding: 0;background-color: #f5f5f5;}.container {width: 80%;margin: 0 auto;padding: 20px;background: #fff;box-shadow: 0 0 10px rgba(0,0,0,0.1);margin-top: 50px;}.auth-form {max-width: 400px;margin: 0 auto;}.flash-messages {color: red;margin-bottom: 20px;}input[type="text"], input[type="password"] {width: 100%;padding: 8px;margin: 8px 0;box-sizing: border-box;}button {background-color: #4CAF50;color: white;padding: 10px 15px;border: none;cursor: pointer;}button:hover {background-color: #45a049;}</style>
</head>
<body><div class="container">{% with messages = get_flashed_messages() %}{% if messages %}<div class="flash-messages">{% for message in messages %}<p>{{ message }}</p>{% endfor %}</div>{% endif %}{% endwith %}{% block content %}{% endblock %}</div>
</body>
</html>

4. templates/index.html(首页)

{% extends "base.html" %}{% block title %}首页 - 1220911101 符亚通{% endblock %}{% block content %}
<div class="welcome">{% if 'username' in session %}<h2>欢迎, {{ username }}!</h2><p>您已成功登录系统</p><a href="{{ url_for('logout') }}"><button>退出登录</button></a>{% else %}<h2>欢迎来到1220911101的Flask登录系统</h2><p>请先<a href="{{ url_for('login') }}">登录</a>或<a href="{{ url_for('register') }}">注册</a></p>{% endif %}
</div>
{% endblock %}

5. templates/login.html(登录页)

{% extends "base.html" %}{% block title %}用户登录 - 1220911101 符亚通{% endblock %}{% block content %}
<div class="auth-form"><h2>用户登录</h2><form method="POST" action="{{ url_for('login') }}"><div><label for="username">用户名:</label><input type="text" id="username" name="username" required></div><div><label for="password">密码:</label><input type="password" id="password" name="password" required></div><button type="submit">登录</button></form><p>还没有账号? <a href="{{ url_for('register') }}">立即注册</a></p>
</div>
{% endblock %}

6. templates/register.html(注册页)

{% extends "base.html" %}{% block title %}用户注册 - 1220911101 符亚通{% endblock %}{% block content %}
<div class="auth-form"><h2>用户注册</h2><form method="POST" action="{{ url_for('register') }}"><div><label for="username">用户名:</label><input type="text" id="username" name="username" required></div><div><label for="password">密码:</label><input type="password" id="password" name="password" required></div><button type="submit">注册</button></form><p>已有账号? <a href="{{ url_for('login') }}">立即登录</a></p>
</div>
{% endblock %}


四.系统测试

1.测试注册流程:
输入空数据、注册已存在用户、成功注册新用户


2.测试登录流程:
错误凭证登录、正确凭证登录


3.测试会话保持:
刷新页面验证状态、测试退出功能


四、思考题

1.当前实现直接将密码明文存储在内存中,这存在什么安全隐患?应该如何改进?

安全隐患分析:
内存泄露风险:如果应用内存被转储,所有用户密码将直接暴露
数据库泄露风险:如果存储到数据库,管理员可以直接查看所有用户密码
违反隐私保护原则:不应存储用户原始密码
改进方案:
from werkzeug.security import generate_password_hash, check_password_hash
# 注册时存储哈希值
users[username] = generate_password_hash(password)
# 登录时验证
if check_password_hash(users[username], password):
 # 验证通过

2.Flask的session是如何工作的?如果需要在多台服务器上部署应用,session存储需要做哪些调整?

默认使用客户端session,数据存储在cookie中
使用密钥签名防止篡改,但不加密内容
包含用户ID等基本信息
多服务器部署调整方案:
# 使用服务器端session存储
from flask_session import Session
app.config['SESSION_TYPE'] = 'redis'  # 或其他服务器端存储
Session(app)

3.现有代码只验证了用户名是否存在,如果要添加以下验证规则应该如何实现:
密码长度不少于6位

用户名只能包含字母和数字
实现代码:
import re

def validate_username(username):
    return bool(re.match('^[a-zA-Z0-9]+$', username))

@app.route('/register', methods=['POST'])
def register():
    username = request.form['username']
    password = request.form['password']
    
    if len(password) < 6:
        flash('密码长度不能少于6位')
    elif not validate_username(username):
        flash('用户名只能包含字母和数字')
    elif username in users:
        flash('用户名已存在')
    else:
        users[username] = generate_password_hash(password)
        flash('注册成功')

4.如果要添加"记住我"功能,使登录状态可以保持更长时间,应该如何修改代码?

from datetime import timedelta

@app.route('/login', methods=['POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        remember = request.form.get('remember')
        
        if check_password_hash(users[username], password):
            session['username'] = username
            if remember:
                # 设置30天过期
                app.permanent_session_lifetime = timedelta(days=30)
                session.permanent = True
 

5.现有错误提示比较简略,如何给用户更友好的错误提示(如密码错误时提示剩余尝试次数)?

# 在应用全局添加尝试次数记录
login_attempts = {}

@app.route('/login', methods=['POST'])
def login():
    username = request.form['username']
    ip = request.remote_addr
    
    # 初始化尝试次数
    if ip not in login_attempts:
   

五、实验完整代码以及资源:

实验链接https://download.csdn.net/download/m0_73951999/91045318?spm=1001.2014.3001.5503

http://www.dtcms.com/a/266550.html

相关文章:

  • 数据结构 之 【堆】(堆的概念及结构、大根堆的实现、向上调整法、向下调整法)(C语言实现)
  • K8s服务发布基础
  • CI/CD持续集成与持续部署
  • 基于大模型的强直性脊柱炎全周期预测与诊疗方案研究
  • 力扣面试150(15/150)
  • 7.4 arm作业
  • 玩转n8n工作流教程(一):Windows系统本地部署n8n自动化工作流(n8n中文汉化)
  • 全平台兼容+3倍加载提速:GISBox将重新定义三维可视化标准
  • Java 实现excel大批量导出
  • 什么是金字塔思维?
  • 三体融合实战:Django+讯飞星火+Colossal-AI的企业级AI系统架构
  • RK-Android11-系统增加一个属性值
  • 【HDMI CEC】 设备 OSD 名称功能详解
  • 《设计模式之禅》笔记摘录 - 3.工厂方法模式
  • 【modbus学习笔记】Modbus协议解析
  • WPF学习(四)
  • 分布式集合通信--学习笔记
  • ComfyUI工作流:一键换背景体验不同场景
  • 如何搭建 OLAP 系统?OLAP与数据仓库有什么关系?
  • 2-2 PID-代码部分
  • Fiddler 中文版怎么配合 Postman 与 Wireshark 做多环境接口调试?
  • Hawk Insight|美国6月非农数据点评:情况远没有看上去那么好
  • 如何将FPGA设计验证效率提升1000倍以上(2)
  • 应急响应靶场——web2——知攻善防实验室
  • 大带宽服务器中冗余技术的功能
  • 新能源汽车功率级测试自动化方案:从理论到实践的革命性突破
  • Python常用医疗AI库以及案例解析(2025年版、上)
  • Nginx + ModSecurity + OWASP CRS + Lua + GEOIP2 构建传统WAF
  • 【ACP】阿里云云计算高级运维工程师--ACP
  • 服务器的IO性能怎么看?