Flask-Login 是一个为 Flask 应用程序设计的扩展,它简化了用户会话管理和认证过程。下面是一个详细的笔记格式讲解,帮助你学习如何使用 Flask-Login。
准备工作
安装 Flask-Login:
在你的 Flask 项目中,首先需要通过 pip 安装 Flask-Login 扩展。
pip install Flask-Login
引入 Flask-Login:
在你的主应用文件(如 app.py
)顶部,引入 Flask-Login 模块。
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
初始化 LoginManager
在 Flask 应用实例化后,创建并初始化 LoginManager 对象。
ext.py
from flask_login import LoginManager
login_manager = LoginManager()
def LoginManagerConfig(app):
login_manager.init_app(app)
login_manager.login_view = 'main_bp.login'
login_manager.login_message = '请先登录'
__init__.py
def create_app():
app = Flask(__name__)
app.config.from_object(Config) # 配置文件
# 注册蓝图
app.register_blueprint(blueprint=routes)
SQLAlchemyConfig(app) # 数据库配置
LoginManagerConfig(app)
return app
用户模型(UserMixin)
为了与 Flask-Login 集成,你的用户模型需要继承 UserMixin
类,这提供了默认的实现,如 is_authenticated
, is_active
, is_anonymous
, 和 get_id
方法。
class User(UserMixin, db.Model): # 假设使用 SQLAlchemy 作为 ORM
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
password_hash = db.Column(db.String(128))
def check_password(self, password):
# 实现密码校验逻辑
pass
用户加载回调
告诉 Flask-Login 如何从数据库加载用户。
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
登录与登出功能
登录
在处理登录请求的视图函数中,使用 login_user()
函数登录用户。
@app.route('/login', methods=['POST'])
def login():
username = request.form['username']
password = request.form['password']
user = User.query.filter_by(username=username).first()
if user and user.check_password(password):
login_user(user) # 登录成功
return redirect(url_for('dashboard')) # 重定向到仪表盘或其他页面
else:
return '用户名或密码错误'
登出
提供一个视图函数让用户登出。
@app.route('/logout')
@login_required # 确保只有登录用户才能访问登出页面
def logout():
logout_user() # 登出用户
return redirect(url_for('index')) # 重定向到首页或其他页面
登录状态检查
使用 @login_required
装饰器可以保护视图,确保用户已登录。
@app.route('/dashboard')
@login_required
def dashboard():
return '欢迎来到仪表盘,{}'.format(current_user.username)
当前登录用户
current_user
变量可以随时用来访问当前登录的用户信息。
@app.route('/profile')
@login_required
def profile():
return '你好,{}!这是你的个人资料页面。'.format(current_user.username)
实例
当然,以下是一个简单的 Flask 应用案例,包括用户注册、登录和登出功能。这个案例假设你已经设置好了 Flask 环境,并且使用 SQLAlchemy 作为 ORM 连接到数据库。
创建模型model
# models.py : 数据库模型
from flask_login import UserMixin
from .ext import db
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
password = db.Column(db.String(120), nullable=False)
迁移文件
flask db init
flask db migrate
flask db upgrade
路由视图函数文件views.py
# 使用 @login_manager.user_loader 装饰器定义用户加载回调函数
# 这个函数根据用户ID从数据库中加载用户对象,用于 Flask-Login 管理会话
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
# 主页路由,渲染主页模板
@routes.route('/')
def index():
return render_template('index.html')
# 注册路由,支持GET和POST方法
@routes.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
username = request.form.get('username') # 获取表单提交的用户名
password = request.form.get('password') # 获取表单提交的密码
hashed_password = generate_password_hash(password) # 对密码进行哈希处理
# 查询数据库中是否有相同的用户名,如果有则提示用户
if User.query.filter_by(username=username).first():
flash('该用户名已被注册,请选择其他用户名。')
return redirect(url_for('main_bp.register')) # 重定向回注册页面
# 创建新用户对象并添加到数据库,然后提交
new_user = User(username=username, password=hashed_password)
db.session.add(new_user)
db.session.commit()
# 注册成功后重定向到登录页面
return redirect(url_for('main_bp.login'))
# GET请求时,渲染注册页面模板
return render_template('register.html')
# 登录路由,支持GET和POST方法
@routes.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
user = User.query.filter_by(username=username).first()
# 验证用户名和密码是否匹配
if user and check_password_hash(user.password, password):
login_user(user) # 登录用户
return redirect(url_for('main_bp.dashboard')) # 登录成功后跳转到仪表盘页面
else:
flash('登录失败,请检查用户名和密码。') # 错误提示
# GET请求或登录失败时,渲染登录页面模板
return render_template('login.html')
# 仪表盘路由,需要登录才能访问
@routes.route('/dashboard')
@login_required
def dashboard():
return render_template('dashboard.html', name=current_user.username) # 传递当前用户姓名到模板
# 登出路由,需要登录才能访问
@routes.route('/logout')
@login_required
def logout():
logout_user() # 注销用户
return redirect(url_for('main_bp.index')) # 注销后重定向到首页
Jinja2模板文件
-
•
index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>Welcome to Flask App</h1>
<p><a href="{{ url_for('main_bp.login') }}">登录</a> 或者 <a href="{{ url_for('main_bp.register') }}">注册</a></p>
</body>
</html>
-
•
register.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<form method="POST" action="{{ url_for('main_bp.register') }}">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required>
<br>
<label for="password">密码:</label>
<input type="password" id="password" name="password" required>
<br>
<button type="submit">注册</button>
</form>
<p>已有账号? <a href="{{ url_for('main_bp.login') }}">登录</a></p>
</body>
</html>
-
•
login.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
<form method="POST" action="{{ url_for('main_bp.login') }}">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required>
<br>
<label for="password">密码:</label>
<input type="password" id="password" name="password" required>
<br>
<button type="submit">登录</button>
</form>
<p>没有账号? <a href="{{ url_for('main_bp.register') }}">注册</a></p>
</body>
</html>
-
•
dashboard.html
<html lang="en">
<head>
<meta charset="UTF-8">
<title>仪表盘</title>
</head>
<body>
<h1>欢迎, {{ name }}!</h1>
<p>这是你的个人仪表盘。</p>
<a href="{{ url_for('main_bp.logout') }}">登出</a>
</body>
</html>
资料与代码
git clone https://gitee.com/ezemeti/FlaskLearn.git
原文始发于微信公众号(索隆程序员):Flask入门 — Flask_Login
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/290003.html