在Web应用中,用户认证是确保系统安全的基础。简单来说,认证就是验证用户身份,权限控制则是判断用户是否有权访问特定资源。本文将使用Flask框架和Session机制,从零开始实现一个简单的用户登录与权限控制系统,适合初学者理解核心概念。
一、准备工作:认识Session与Flask基础¶
在开始之前,我们先了解两个核心概念:
- 用户认证:通过用户名/密码等方式验证用户身份,确保只有合法用户能访问系统。
- Session:服务器为每个用户创建的临时存储区域,用于保存用户状态(如登录状态、用户信息)。Flask的
session对象可直接操作Session,无需额外数据库支持。
环境准备:
确保已安装Flask:
pip install flask
二、创建基础Flask应用与Session配置¶
首先,我们创建一个简单的Flask应用,并配置Session密钥(这是必须的,用于加密Session数据):
from flask import Flask, render_template, request, session, redirect, url_for, flash
from functools import wraps
app = Flask(__name__)
app.secret_key = 'your_secret_key_here' # 必须设置,用于加密Session(开发时可随便写,生产需复杂随机字符串)
三、实现登录功能:验证身份与设置Session¶
登录功能需要两个核心部分:登录表单和验证逻辑。
1. 登录表单(HTML模板)¶
创建templates/login.html文件,编写登录表单(支持用户名/密码输入和错误提示):
<!DOCTYPE html>
<html>
<head>
<title>登录</title>
</head>
<body>
<h1>用户登录</h1>
<!-- 显示错误信息(如用户名/密码错误) -->
{% with messages = get_flashed_messages() %}
{% if messages %}
{% for message in messages %}
<p style="color: red;">{{ message }}</p>
{% endfor %}
{% endif %}
{% endwith %}
<form method="POST">
<div>
<label>用户名:</label>
<input type="text" name="username" required>
</div>
<div>
<label>密码:</label>
<input type="password" name="password" required>
</div>
<button type="submit">登录</button>
</form>
</body>
</html>
2. 处理登录请求(验证用户并设置Session)¶
在app.py中添加登录路由,处理表单提交并验证用户:
# 模拟用户数据库(实际项目中可连接MySQL/PostgreSQL等)
USER_DATABASE = {
'admin': 'admin123', # 用户名-密码对
'guest': 'guest456'
}
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
# 验证用户是否存在且密码正确
if username in USER_DATABASE and USER_DATABASE[username] == password:
session['username'] = username # 设置Session,保存用户身份
return redirect(url_for('dashboard')) # 登录成功跳转到个人中心
else:
flash('用户名或密码错误') # 错误提示,通过模板显示
# GET请求直接渲染登录页面
return render_template('login.html')
四、权限控制:保护需要登录的页面¶
很多页面(如个人中心、后台管理)需要用户已登录才能访问。我们通过@login_required装饰器实现权限检查:
1. 编写登录验证装饰器¶
在app.py中添加装饰器函数,检查Session是否存在用户信息:
def login_required(f):
@wraps(f) # 保留原函数元信息
def decorated_function(*args, **kwargs):
if 'username' not in session: # 如果Session中没有用户名,说明未登录
flash('请先登录')
return redirect(url_for('login')) # 重定向到登录页
return f(*args, **kwargs) # 已登录,继续执行目标函数
return decorated_function
2. 保护个人中心页面¶
创建需要登录的个人中心页面,使用装饰器保护:
@app.route('/dashboard')
@login_required # 必须登录才能访问
def dashboard():
return render_template('dashboard.html', username=session['username']) # 传递用户名到模板
五、实现登出功能¶
登出需要清除Session中的用户信息,让用户状态失效:
@app.route('/logout')
def logout():
session.pop('username', None) # 从Session中删除用户名
flash('已成功登出')
return redirect(url_for('index')) # 登出后跳回首页
六、完善页面与测试¶
为了让用户体验更完整,我们补充首页和登出后的页面:
1. 首页模板(templates/index.html)¶
允许未登录用户访问,显示登录入口:
<!DOCTYPE html>
<html>
<head>
<title>首页</title>
</head>
<body>
<h1>欢迎来到系统</h1>
<a href="{{ url_for('login') }}">登录</a> | <a href="{{ url_for('dashboard') }}">个人中心</a>
</body>
</html>
2. 个人中心模板(templates/dashboard.html)¶
仅登录用户可见,显示用户名和登出入口:
<!DOCTYPE html>
<html>
<head>
<title>个人中心</title>
</head>
<body>
<h1>欢迎,{{ username }}!</h1>
<a href="{{ url_for('logout') }}">登出</a>
</body>
</html>
3. 启动应用并测试¶
运行app.py:
if __name__ == '__main__':
app.run(debug=True)
测试流程:
1. 访问 http://127.0.0.1:5000,首页显示正常,点击“个人中心”会被重定向到登录页。
2. 输入测试账号(如admin/admin123或guest/guest456),登录成功后进入个人中心。
3. 点击“登出”,Session被清除,再次访问个人中心会重定向到登录页。
七、总结¶
通过本文,我们学习了:
1. Session基础:使用Flask的session对象存储用户状态,通过secret_key加密数据。
2. 用户认证:通过表单提交和硬编码数据库实现简单登录验证。
3. 权限控制:使用装饰器检查Session是否存在,保护需要登录的页面。
4. 用户登出:通过session.pop()清除用户状态。
扩展方向:
- 连接数据库验证用户(如使用SQLAlchemy)。
- 实现多角色权限(如普通用户/管理员)。
- 添加密码加密(避免明文存储,使用bcrypt等库)。
Flask Session为初学者提供了简单易用的身份验证方案,掌握这些基础后,可逐步构建更复杂的Web应用。