繁体   English   中英

Flask-Admin 视图需要 Flask-basicAuth auth 装饰器

[英]Flask-basicAuth auth required decorator for Flask-Admin views

我目前正在使用 Flask 制作一个后端应用程序来管理基于组织的用户消费的资源。

由于我使用 Flask-SQLAlchemy,我决定使用 Flask-Admin 作为数据库的管理视图,但我在保护视图时遇到了问题。

我正在尝试使用 Flask-BasicAuth 来保护管理视图,但由于路由是自动生成的,我无法向其中添加 @basic-auth.required 装饰器。 强制站点使用 Flask-BasicAuth 会阻塞资源端点,因此不是一个好的解决方案。

尝试过这样的事情,但它不起作用:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin
from flask_admin.contrib.sqla import ModelView
from flask_basicauth import BasicAuth

app = Flask(__name__)
db = SQLAlchemy(app)
basic_auth = BasicAuth(app)
admin = Admin(app)

class Module(db.Model):
  __tablename__='Modules'
  name = db.Column(db.String(30), unique=True, nullable=False)

@basic_auth.required
class AdminView(ModelView):
  pass

admin.add_view(AdminView(Module, db.session))

TL;DR:Flask 管理员假设我使用登录和会话管理器。 Flask BasicAuth 假设我可以手动声明路由。 需要在不阻塞资源端点的情况下以某种方式集成它们。

我在实施它时遇到了同样的问题。 @basic_auth.required 装饰器不起作用。 相反,我们必须调整几个flask_admin 类以使其与BasicAuth 兼容。 在参考了数十个资源后,这是我成功实施的方法!

只是提到我正在使用:Python 3.6.9,Flask==1.1.1,Flask-Admin==1.5.4,Flask-BasicAuth==0.2.0

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin, AdminIndexView
from flask_admin.contrib.sqla import ModelView
from flask_basicauth import BasicAuth
from werkzeug.exceptions import HTTPException

app = Flask(__name__)
db = SQLAlchemy(app)
basic_auth = BasicAuth(app)

class Module(db.Model):
  __tablename__='Modules'
  name = db.Column(db.String(30), unique=True, nullable=False)

"""
The following three classes are inherited from their respective base class,
and are customized, to make flask_admin compatible with BasicAuth.
"""
class AuthException(HTTPException):
    def __init__(self, message):
        super().__init__(message, Response(
            "You could not be authenticated. Please refresh the page.", 401,
            {'WWW-Authenticate': 'Basic realm="Login Required"'} ))

class MyModelView(ModelView):
    def is_accessible(self):
        if not basic_auth.authenticate():
            raise AuthException('Not authenticated.')
        else:
            return True
    def inaccessible_callback(self, name, **kwargs):
        return redirect(basic_auth.challenge())

class MyAdminIndexView(AdminIndexView):
    def is_accessible(self):
        if not basic_auth.authenticate():
            raise AuthException('Not authenticated.')
        else:
            return True
    def inaccessible_callback(self, name, **kwargs):
        return redirect(basic_auth.challenge())

admin = Admin(app, index_view=MyAdminIndexView())

admin.add_view(MyModelView(Module, db.session))

官方文档说没有简单的方法可以仅在您的管理页面上实现它。 但是,我找到了一种解决方法。 您可能需要修改flask 中的一些现有类以使其与基本身份验证兼容。 将这些添加到您的代码中。 仅供参考,您需要从烧瓶中导入响应。

class ModelView(sqla.ModelView):
    def is_accessible(self):
        if not basic_auth.authenticate():
            raise AuthException('Not authenticated.')
        else:
            return True

    def inaccessible_callback(self, name, **kwargs):
    return redirect(basic_auth.challenge())
from werkzeug.exceptions import HTTPException


class AuthException(HTTPException):
    def __init__(self, message):
        super().__init__(message, Response(
            "You could not be authenticated. Please refresh the page.", 401,
            {'WWW-Authenticate': 'Basic realm="Login Required"'}
        ))

然后像这样正常添加管理视图

admin = Admin(app)
admin.add_view(ModelView(Module, db.session))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM