使用 Flask 实现简单的用户认证系统,实现登录限制
引言
在 Web 开发中,用户认证是一个非常常见且重要的功能。本篇文章将带领大家一步步构建一个简单的用户认证系统,使用 Flask 框架、哈希密码和 Session 来管理用户的登录状态。通过这个示例,您将了解如何在 Flask 中处理用户登录、验证和登出功能。
1. 环境准备
在开始之前,确保您的环境中安装了以下库:
- Flask:一个轻量级的 Web 应用框架。
- Werkzeug:Flask 的依赖库,提供了密码哈希函数。
您可以使用以下命令安装所需的库:
pip install flask werkzeug
2. 项目结构
项目的代码全部放在一个 Python 脚本中,文件名为 app.py
。在实际项目中,建议将代码模块化,以提高可维护性。
3. 代码解析
下面是完整的代码,我们将逐步解析每一部分的功能。
# 导入 Flask 库中的 Flask 应用类、request 对象、make_response 函数、redirect 重定向函数、url_for 生成 URL 的函数、以及 session 会话对象
from flask import Flask, request, make_response, redirect, url_for, session
# 导入 werkzeug 库中的 generate_password_hash 生成密码哈希函数 和 check_password_hash 校验哈希密码函数
from werkzeug.security import generate_password_hash, check_password_hash
# 创建 Flask 应用实例,传入当前模块的名称作为参数
app = Flask(__name__)
# 设置 Flask 应用的密钥,用于对 session 数据进行加密,保护敏感信息
app.secret_key = 'your_secret_key'
# 模拟的用户数据库,存储用户的用户名和经过哈希加密后的密码(防止明文存储密码)
users = {
'user1': generate_password_hash('password1'), # 'user1' 用户的密码经过哈希加密后存储
'user2': generate_password_hash('password2') # 'user2' 用户的密码经过哈希加密后存储
}
# 定义 '/login' 路由,并允许 GET 和 POST 两种请求方法
@app.route('/login', methods=['GET', 'POST'])
def login():
# 检查请求方法是否为 POST(表明用户提交了登录表单)
if request.method == 'POST':
# 获取用户通过表单提交的用户名
username = request.form['username']
# 获取用户通过表单提交的密码
password = request.form['password']
# 从模拟的用户数据库中获取与用户名对应的哈希密码(若用户名不存在则返回 None)
user_hashed_password = users.get(username)
# 检查用户是否存在并且输入的密码与数据库中的哈希密码匹配
if user_hashed_password and check_password_hash(user_hashed_password, password):
# 如果验证通过,设置 session,表示用户已登录
session['logged_in'] = True
# 重定向用户到欢迎页面
return redirect(url_for('welcome'))
else:
# 如果用户名或密码错误,返回错误信息
return 'Invalid username or password'
# 如果请求方法为 GET,返回包含用户名和密码输入框的登录表单
return '''
<form method="post">
<!-- 用户名输入框 -->
Username: <input type="text" name="username"><br>
<!-- 密码输入框 -->
Password: <input type="password" name="password"><br>
<!-- 提交按钮 -->
<input type="submit" value="Login">
</form>
'''
# 定义 '/welcome' 路由,用于欢迎已登录的用户
@app.route('/welcome')
def welcome():
# 检查 session 中是否存在 'logged_in' 并且其值为 True,表明用户已登录
if session.get('logged_in'):
# 如果用户已登录,返回欢迎信息
return 'Welcome! You are logged in.'
else:
# 如果用户未登录,重定向到登录页面
return redirect(url_for('login'))
# 定义 '/logout' 路由,用于处理用户登出
@app.route('/logout')
def logout():
# 从 session 中移除 'logged_in' 键,表示用户登出
session.pop('logged_in', None)
# 重定向到登录页面
return redirect(url_for('login'))
# 检查脚本是否直接运行(而非被导入为模块),如果是,启动 Flask 应用
if __name__ == '__main__':
# 启动应用,并开启调试模式以便在开发时自动重载和显示调试信息
app.run(debug=True)
此代码通过 Flask 实现了一个简单的用户认证系统,包含用户登录、会话管理和登出功能。每一步都有详细的注释,帮助理解整个流程。
3.1 导入必要的模块
from flask import Flask, request, make_response, redirect, url_for, session
from werkzeug.security import generate_password_hash, check_password_hash
- Flask:核心框架,用于创建 Web 应用。
- request:处理请求数据。
- redirect, url_for:用于页面重定向。
- session:用于保存用户会话信息。
- generate_password_hash, check_password_hash:用于生成和验证密码哈希,增强安全性。
3.2 初始化 Flask 应用
app = Flask(__name__)
app.secret_key = 'your_secret_key'
- app = Flask(name):创建 Flask 应用实例。
- app.secret_key:设置应用的密钥,用于加密 session,确保安全性。注意:在生产环境中,应使用更安全的随机密钥,并将其保存在环境变量或配置文件中。
3.3 模拟用户数据库
users = {
'user1': generate_password_hash('password1'),
'user2': generate_password_hash('password2')
}
- 这里我们使用一个字典来模拟用户数据库,键为用户名,值为经过哈希处理的密码。
- generate_password_hash(‘password’):对密码进行哈希处理,防止明文存储密码,提高安全性。
3.4 登录路由 /login
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
# 处理登录逻辑
return '''
<form method="post">
<!-- 登录表单 -->
</form>
'''
3.4.1 处理 GET 请求
- 当用户首次访问
/login
时,返回一个包含用户名和密码输入框的登录表单。
3.4.2 处理 POST 请求
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
user_hashed_password = users.get(username)
if user_hashed_password and check_password_hash(user_hashed_password, password):
session['logged_in'] = True
return redirect(url_for('welcome'))
else:
return 'Invalid username or password'
- 获取用户输入:从表单中获取用户名和密码。
- 验证用户:
- users.get(username):从用户数据库中获取对应的密码哈希。
- check_password_hash(user_hashed_password, password):验证输入的密码与存储的哈希是否匹配。
- 设置 Session:如果验证成功,在 session 中设置
logged_in
键为True
,表示用户已登录。 - 错误处理:如果验证失败,返回错误信息。
3.5 欢迎页面 /welcome
@app.route('/welcome')
def welcome():
if session.get('logged_in'):
return 'Welcome! You are logged in.'
else:
return redirect(url_for('login'))
- 检查登录状态:通过检查 session 中的
logged_in
键来判断用户是否已登录。 - 返回欢迎信息或重定向:已登录则显示欢迎信息,未登录则重定向到登录页面。
3.6 登出路由 /logout
@app.route('/logout')
def logout():
session.pop('logged_in', None)
return redirect(url_for('login'))
- 清除 Session:使用
session.pop
方法移除logged_in
键,表示用户已登出。 - 重定向:登出后重定向到登录页面。
3.7 运行应用程序
if __name__ == '__main__':
app.run(debug=True)
- app.run(debug=True):运行 Flask 应用,启用调试模式。注意:在生产环境中,不要启用调试模式。
4. 运行和测试
-
启动应用程序:
python app.py
-
访问登录页面:
在浏览器中打开
http://localhost:5000/login
,您将看到登录表单。 -
使用有效的凭据登录:
- 用户名:
user1
,密码:password1
- 用户名:
user2
,密码:password2
- 用户名:
-
测试登录功能:
- 输入正确的用户名和密码,应被重定向到欢迎页面并显示欢迎信息。
- 输入错误的用户名或密码,应显示错误信息。
-
测试登出功能:
- 访问
http://localhost:5000/logout
,将清除登录状态并重定向到登录页面。
- 访问
5. 安全性注意事项
- 密码存储:在实际应用中,应使用数据库来存储用户信息,并确保密码经过哈希处理。
- Session 安全:
secret_key
应该是随机且安全的,建议从环境变量或配置文件中读取。 - HTTPS:在生产环境中,确保使用 HTTPS 来加密数据传输,保护用户的敏感信息。
6. 总结
通过本篇文章,我们构建了一个简单的用户认证系统,了解了如何使用 Flask、哈希密码和 Session 来管理用户的登录状态。希望这个示例能帮助您更好地理解 Flask 中的用户认证机制,并为您的实际项目提供参考。