python - 在 Flask 中安全区分管理员和其他用户的最简单方法

请原谅我的天真,但我一直在研究 Flask 中角色身份验证的各种解决方案,似乎不再维护几个扩展。这让我想知道我是否需要除了 Flask 登录之外的任何一个来实现我的目的。

在我的路由和模板中使用 if current_user.is_admin 是否足以区分管理员和其他用户?如果是这样,与使用 https://flask-security-too.readthedocs.io/en/stable/ 之类的方法相比,这种方法是否有任何安全问题或其他缺点需要考虑?我意识到这种方法会变得非常重复——我可以创建一个装饰器来执行这个检查吗?我还没有对装饰器有扎实的把握。

路线.py

@app.route('/students', methods=['GET', 'POST'])
@login_required
def students():
    form = StudentForm()
    if current_user.is_admin:
        if form.validate_on_submit():
            student = Student(student_name=form.student_name.data, last_name=form.last_name.data, \
            student_email=form.student_email.data, parent_name=form.parent_name.data, \
            parent_email=form.parent_email.data, secondary_email=form.secondary_email.data, \
            timezone=form.timezone.data, location=form.location.data, status=form.status.data, \
            tutor=form.tutor_id.data)
            try:
                db.session.add(student)
                db.session.commit()
            except:
                db.session.rollback()
                flash(student.student_name + ' could not be added', 'error')
                return redirect(url_for('students'))
            flash(student.student_name + ' added')
            return redirect(url_for('students'))
        return render_template('students.html', title="Students", form=form)
    else:
        flash('You must have administrator privileges to access this page.', 'error')
        logout_user()
        return redirect(url_for('login'))

模型.py

class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    ...
    is_admin = db.Column(db.Boolean)

回答1

将反对票作为暗示进行更多挖掘,我相信我有合适的东西。创建了以下 admin_required 装饰器:

def admin_required(f):
    @login_required
    @wraps(f)
    def wrap(*args, **kwargs):
        if current_user.is_admin:
            return f(*args, **kwargs)
        else:
            flash('You must have administrator privileges to access this page.', 'error')
            logout_user()
            return redirect(login_url('login', next_url=request.url))
    return wrap

请注意,在您的登录视图中验证 next_url 以避免网络钓鱼重定向很重要:

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        ...
        next = request.args.get('next')
        if not next or url_parse(next).netloc != '':
            next = url_for('default_redirect')
        return redirect(next)
    return render_template('login.html', title="Login", form=form)

感谢@Miguel Grinberg 提供 url 验证代码,感谢您使用 Mega Flask 教程首次涉足后端编码。

相似文章

随机推荐

最新文章