如何在MySQL数据库环境下使用Flask-Login实现用户登录控制
解决Flask-Login + MySQL的用户登录/首页访问控制问题
1. 适配MySQL的Flask-Login核心:User类实现
Flask-Login不依赖SQLAlchemy,只要你的User类满足识别用户的核心规则就行——最简单的方式是继承UserMixin(帮你自动实现所需的4个方法),再从MySQL中映射用户数据:
from flask_login import UserMixin class User(UserMixin): def __init__(self, user_id, username, password): self.id = user_id # Flask-Login必须用id属性识别用户 self.username = username self.password = password # 如果你不想继承UserMixin,手动实现以下4个方法也可以: # def is_authenticated(self): return True # def is_active(self): return True # def is_anonymous(self): return False # def get_id(self): return str(self.id)
2. 配置LoginManager,对接MySQL查询
LoginManager需要一个user_loader回调,用来根据用户ID从MySQL中加载用户实例。这里以pymysql为例实现MySQL查询:
from flask import Flask from flask_login import LoginManager import pymysql app = Flask(__name__) app.secret_key = '你的自定义密钥' # 必须设置,Flask-Login依赖session存储登录状态 # 初始化LoginManager login_manager = LoginManager() login_manager.init_app(app) login_manager.login_view = 'login' # 未登录用户访问受保护页面时,跳转的登录路由 # MySQL连接配置(根据你的实际数据库信息修改) db_config = { 'host': 'localhost', 'user': 'root', 'password': '你的数据库密码', 'database': '你的数据库名' } # 实现user_loader回调:根据user_id从MySQL取用户 @login_manager.user_loader def load_user(user_id): conn = pymysql.connect(**db_config) cursor = conn.cursor() cursor.execute("SELECT id, username, password FROM users WHERE id = %s", (user_id,)) user_data = cursor.fetchone() cursor.close() conn.close() if user_data: return User(user_data[0], user_data[1], user_data[2]) return None
3. 登录逻辑:用login_user标记用户登录状态
登录路由中验证用户名密码后,调用login_user即可完成登录(Flask-Login会自动处理session,不用手动操作):
from flask import render_template, redirect, url_for, flash, request from flask_login import login_user from werkzeug.security import check_password_hash # 生产环境一定要用哈希密码验证 @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': username = request.form['username'] password = request.form['password'] # 从MySQL查询用户 conn = pymysql.connect(**db_config) cursor = conn.cursor() cursor.execute("SELECT id, username, password_hash FROM users WHERE username = %s", (username,)) user_data = cursor.fetchone() cursor.close() conn.close() # 验证密码(注意:生产环境要存密码哈希,别存明文) if user_data and check_password_hash(user_data[2], password): user = User(user_data[0], user_data[1], user_data[2]) login_user(user) # 标记用户已登录 flash('登录成功!', category='success') return redirect(url_for('home')) else: flash('用户名或密码错误', category='error') return render_template('login.html')
4. 首页访问控制:已登录可访问,未登录自动跳转
直接给首页路由加@login_required装饰器,Flask-Login会自动拦截未登录用户,跳转到你设置的登录页:
from flask_login import login_required, current_user @app.route('/') @app.route('/home') @login_required def home(): # current_user可以直接获取当前登录的用户实例 return render_template('home.html', username=current_user.username)
5. 优化登出逻辑
你原代码中的session.pop是多余的,logout_user()已经会清空Flask-Login管理的登录状态,简化后:
from flask_login import login_required, logout_user, flash, redirect, url_for @app.route('/logout') @login_required def logout(): logout_user() flash('已成功登出,欢迎再次回来!', category='success') return redirect(url_for('login')) # 登出后跳转登录页,也可以跳首页(会自动拦截转登录)
关键注意事项
- 密码安全:绝对不要存明文密码,用
werkzeug.security.generate_password_hash生成哈希后存入数据库,登录时用check_password_hash验证。 - MySQL连接优化:实际项目不要每次请求都新建连接,建议用连接池(比如
pymysqlpool),或者直接用你熟悉的Flask-SQLAlchemy连接MySQL(SQLAlchemy本身支持MySQL,配置数据库URI为mysql+pymysql://用户名:密码@主机/数据库名即可)。 - current_user:在视图或模板中,导入
from flask_login import current_user即可随时获取当前登录用户的信息。
内容的提问来源于stack exchange,提问作者fierylion
相关产品推荐
相关产品推荐

