关于Flask-Login多用户表登陆
为什么发帖
- 课设要求做一个面向多种用户类型的网站,且每个用户类型的操作界面、属性、权限都不一样。
- 想过使用 一个 User 表,附上role属性。但每个角色的属性都不一样而且有比较大的差别,便作罢了
- 我用了三个用户表,完成编写后,觉得不太简洁,想问一下大家有没有别的思路
- 直接对session进行操作会不会很粗暴
- 看了叫做flask-login-multi的扩展,18年就不再维护了
数据库模型
class BaseUser(db.Model, UserMixin):
__abstract__ = True
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(30))
password_hash = db.Column(db.String(128))
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
class Student(BaseUser):
stu_id = db.Column(db.String(32), unique=True, index=True)
role = db.Column(db.Integer, default=0)
# ...
class Teacher(BaseUser):
tea_id = db.Column(db.String(32), unique=True, index=True)
role = db.Column(db.Integer, default=1)
# ...
class Admin(BaseUser):
adm_id = db.Column(db.String(32), unique=True, index=True)
role = db.Column(db.Integer, default=2)
# ...
登录表单
class LoginForm(FlaskForm):
id = StringField('ID', validators=[DataRequired()])
password = PasswordField(u'密码', validators=[DataRequired()])
role = RadioField(u'身份', choices=[('student', u'学生'), ('teacher', u'老师'), ('admin', u'管理员')],
validators=[DataRequired()])
remember = BooleanField(u'记住我')
submit = SubmitField(u'登录')
登录视图
@bp.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
return redirect(url_for('main.index'))
form = LoginForm()
if form.validate_on_submit():
id = form.id.data
role = form.role.data
if role == 'student':
user = Student.query.filter_by(stu_id=id).first()
if user is not None and user.check_password(form.password.data):
login_user(user, remember=form.remember.data)
session['role'] = 'student'
else:
flash(u'用户名或密码错误', 'warning')
return redirect(url_for('.login'))
if role == 'teacher':
user = Teacher.query.filter_by(tea_id=id).first()
if user is not None and user.check_password(form.password.data):
login_user(user, remember=form.remember.data)
session['role'] = 'teacher'
else:
flash(u'用户名或密码错误', 'warning')
return redirect(url_for('.login'))
if role == 'admin':
user = Admin.query.filter_by(adm_id=id).first()
if user is not None and user.check_password(form.password.data):
login_user(user, remember=form.remember.data)
session['role'] = 'admin'
else:
flash(u'用户名或密码错误', 'warning')
return redirect(url_for('.login'))
flash(u'{}登陆成功'.format(user.name), 'success')
return redirect(url_for('main.index'))
return render_template('auth/login.html', form=form)
login_manager 的 userloader
@login.user_loader
def load_user(user_id):
if session.get('role') == 'student':
return Student.query.get(int(user_id))
elif session.get('role') == 'teacher':
return Teacher.query.get(int(user_id))
else:
return Admin.query.get(int(user_id))
用户过滤装饰器
def admin_required(func):
@wraps(func)
def decorated_function(*args, **kwargs):
if not current_user.role == 2:
return abort(403)
return func(*args, **kwargs)
return decorated_function
def student_required(func):
@wraps(func)
def decorated_function(*args, **kwargs):
if not current_user.role == 0:
return abort(403)
return func(*args, **kwargs)
return decorated_function
def teacher_required(func):
@wraps(func)
def decorated_function(*args, **kwargs):
if not current_user.role == 1:
return abort(403)
return func(*args, **kwargs)
return decorated_function
谢谢你可以看到这里,如果你有更好的解决方法,麻烦告诉我,再次感谢!