22 Flask 用户登录逻辑实践

22 Flask 用户登录逻辑实践

在本节中,我们将实现一个简单的用户登录逻辑,利用 Flask 框架来处理用户认证。我们将使用 Flask-Login 扩展框架来管理用户会话。

环境准备

首先,确保你已经安装了 Flask 和 Flask-Login。你可以使用以下命令进行安装:

1
pip install Flask Flask-Login

创建 Flask 应用

首先,我们要创建一个基本的 Flask 应用并初始化 Flask-Login

1
2
3
4
5
6
7
8
9
10
11
from flask import Flask, render_template, redirect, url_for, request, flash
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user

app = Flask(__name__)
app.secret_key = 'your_secret_key'

login_manager = LoginManager()
login_manager.init_app(app)

# 用户数据示例
users = {'admin': {'password': 'admin123'}}

创建用户模型

我们将定义一个简单的用户模型。对于演示简洁性,我们将用户信息存储在一个字典中。

1
2
3
4
5
6
7
class User(UserMixin):
def __init__(self, id):
self.id = id

@login_manager.user_loader
def load_user(user_id):
return User(user_id)

登录视图

接下来,我们将创建一个登录视图,它将处理表单提交并验证用户。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']

user = users.get(username)
if user and user['password'] == password:
user_obj = User(username)
login_user(user_obj)
return redirect(url_for('protected'))

flash('用户名或密码错误')

return render_template('login.html')

登录模板

创建一个简单的登录表单 login.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!doctype html>
<html>
<head>
<title>登录</title>
</head>
<body>
<h1>用户登录</h1>
<form method="POST">
<input type="text" name="username" placeholder="用户名" required>
<input type="password" name="password" placeholder="密码" required>
<button type="submit">登录</button>
</form>
<p style="color:red;">{{ get_flashed_messages()[0] }}</p>
</body>
</html>

受保护的视图

为了确保只有已登录的用户可以访问某些页面,我们需要添加一个受保护的视图。

1
2
3
4
@app.route('/protected')
@login_required
def protected():
return f'欢迎,{current_user.id}!你已成功登录。'

注销功能

添加注销功能,让用户可以退出登录。

1
2
3
4
5
@app.route('/logout')
@login_required
def logout():
logout_user()
return redirect(url_for('login'))

运行应用

最后,添加运行 Flask 应用的代码:

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

总结

在本节中,我们实现了一个简单的用户登录逻辑,包括用户验证、登录和注销功能。我们使用了 Flask-Login 来管理用户会话,确保用户能够安全地访问受保护的内容。通过结合代码和示例,我们可以全面理解 Flask 的用户认证机制。

23 Flask 会话管理

23 Flask 会话管理

在 Flask 中,会话(Session)用于在多个请求之间存储用户的状态信息,例如用户登录状态、购物车内容等。Flask 默认提供了一种简单的会话管理方式。接下来,我们将通过实际案例来深入理解 Flask 的会话管理。

Flask 会话的基本概念

Flask 的会话是用客户端 cookie 存储的一种数据。在 Flask 中,可以方便地使用 session 对象来存取数据。存储在会话中的数据在客户端以 cookie 的形式存在,但为了安全起见,Flask 会对其进行加密。

会话的配置

在使用会话之前,我们需要在 Flask 应用中设置一个密钥(SECRET_KEY),用于加密会话数据。

1
2
3
4
from flask import Flask, session

app = Flask(__name__)
app.secret_key = 'your_secret_key' # 设置密钥

设置会话数据

我们可以通过 session 对象来设置和获取会话数据。以下是一个简单的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from flask import Flask, session, redirect, url_for, request

app = Flask(__name__)
app.secret_key = 'your_secret_key'

@app.route('/setname', methods=['POST'])
def set_name():
# 从表单获取用户名并存入会话
session['username'] = request.form['username']
return redirect(url_for('index'))

@app.route('/')
def index():
# 获取会话中的用户名
username = session.get('username', 'Guest')
return f'Hello, {username}!'

在上面的代码中,用户通过 /setname 路由提交用户名,该用户名会被存储在会话中。在主页面 / 中,我们可以读取这个会话值并展示给用户。

清除会话数据

如果我们想要清除某个会话数据,可以使用 session.pop() 方法:

1
2
3
4
5
@app.route('/logout')
def logout():
# 清除会话数据
session.pop('username', None)
return redirect(url_for('index'))

在这个例子中,访问 /logout 路由将会清除存储在会话中的用户名。

生命周期

Flask 默认情况下,会话数据在用户浏览器关闭后将会丢失。若想使会话持久化,可以设置 permanent 属性:

1
2
3
4
5
6
@app.route('/setname', methods=['POST'])
def set_name():
session['username'] = request.form['username']
session.permanent = True # 设置会话为持久化
app.permanent_session_lifetime = timedelta(days=1) # 设置会话过期时间
return redirect(url_for('index'))

注意事项

  1. 安全性:确保设置一个随机且复杂的 SECRET_KEY,以避免会话数据被伪造。
  2. 存储大小:由于会话数据存储在客户端 cookie 中,所以请注意数据的大小,避免过大的数据影响 HTTP 负载。

实际案例

我们可以构建一个简单的用户登录示例,利用会话管理实现用户的登录状态。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from flask import Flask, session, redirect, url_for, request, render_template

app = Flask(__name__)
app.secret_key = 'your_secret_key'

# 模拟用户数据库
users = {'admin': 'password'}

@app.route('/')
def index():
username = session.get('username', 'Guest')
return render_template('index.html', username=username)

@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
if users.get(username) == password:
session['username'] = username # 设置会话数据
return redirect(url_for('index'))
return render_template('login.html')

@app.route('/logout')
def logout():
session.pop('username', None) # 清除会话数据
return redirect(url_for('index'))

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

HTML 模板

templates/index.htmltemplates/login.html 中创建简单的 HTML 表单:

index.html

1
2
3
4
5
6
7
8
9
10
11
12
<!doctype html>
<html>
<head><title>Home</title></head>
<body>
<h1>Hello, {{ username }}!</h1>
{% if username != 'Guest' %}
<a href="{{ url_for('logout') }}">Logout</a>
{% else %}
<a href="{{ url_for('login') }}">Login</a>
{% endif %}
</body>
</html>

login.html

1
2
3
4
5
6
7
8
9
10
11
12
<!doctype html>
<html>
<head><title>Login</title></head>
<body>
<h1>Login</h1>
<form method="post">
Username: <input type="text" name="username">
Password: <input type="password" name="password">
<input type="submit" value="Login">
</form>
</body>
</html>

总结

通过以上示例,我们了解了 Flask 的会话管理,包括如何设置、获取和清除会话数据。掌握这些基本概念后,可以在实际项目中有效地管理用户状态。会话管理是 Web 应用开发中非常重要的一环,希望本篇文章能帮助你更好地理解和使用 Flask 的会话功能。

24 Flask 权限控制实战

24 Flask 权限控制实战

在现代Web应用中,用户权限控制是非常重要的一部分。Flask 提供了灵活的方式来实现这一功能。通过简单的示例,我们将深入了解如何在 Flask 中实现用户权限控制。

设置 Flask 项目

首先,确保你已经安装了 Flask。如果还没有安装,可以使用以下命令:

1
pip install Flask

接下来,我们创建一个基本的 Flask 应用结构:

1
2
3
4
5
6
7
8
9
10
from flask import Flask, redirect, url_for, session, request

app = Flask(__name__)
app.secret_key = 'your_secret_key'

# 假设的用户数据库
users = {
'admin': {'password': 'admin123', 'role': 'admin'},
'user': {'password': 'user123', 'role': 'user'}
}

用户登录

我们需要一个简单的登录功能以便用户验证和角色分配:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']

user = users.get(username)

if user and user['password'] == password:
session['username'] = username
session['role'] = user['role']
return redirect(url_for('dashboard'))

return 'Invalid username or password'

return '''
<form method="POST">
Username: <input type="text" name="username"><br>
Password: <input type="password" name="password"><br>
<input type="submit" value="Login">
</form>
'''

设定权限装饰器

为了控制不同角色用户的访问权限,我们可以创建一个权限装饰器:

1
2
3
4
5
6
7
8
9
10
11
12
from functools import wraps
from flask import abort

def role_required(role):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if 'role' not in session or session['role'] != role:
abort(403) # Forbidden
return f(*args, **kwargs)
return decorated_function
return decorator

创建受保护的路由

现在,我们可以创建一些受权限控制的路由:

1
2
3
4
5
6
7
8
9
10
11
12
13
@app.route('/dashboard')
def dashboard():
return f'Welcome, {session["username"]}! Your role is {session["role"]}. <a href="/logout">Logout</a>'

@app.route('/admin')
@role_required('admin')
def admin_dashboard():
return 'This is the admin dashboard.'

@app.route('/user')
@role_required('user')
def user_dashboard():
return 'This is the user dashboard.'

登出功能

为了完整性,我们添加一个登出路由:

1
2
3
4
5
@app.route('/logout')
def logout():
session.pop('username', None)
session.pop('role', None)
return redirect(url_for('login'))

启动应用

最后,添加以下代码来启动 Flask 应用:

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

案例测试

  1. 启动应用后,访问 /login
  2. 输入 adminadmin123,你将进入 /dashboard
  3. 访问 /admin,如果一切正常,你可以看到管理员界面。
  4. 如果尝试访问 /user,你会被拒绝(403 Forbidden)。

使用这种方式,我们可以轻松地管理用户的权限,确保只有具有适当角色的用户才能访问特定资源。

小结

本文展示了如何在 Flask 应用中实现简单的权限控制。通过使用 Flask 的 session 功能和自定义装饰器,我们能够有效地管理用户访问,确保应用的安全性。随着项目的发展,你可能需要考虑更复杂的权限管理方案,比如使用数据库存储用户角色和权限。