【问题标题】:Dash Client Side Error Handling on CallbacksDash 客户端对回调的错误处理
【发布时间】:2022-07-04 00:42:46
【问题描述】:

我们的一些 Dash 回调涉及调用通过 OAuth 授权的外部 API(正在使用 Authlib)。当用户注销时,他们的 OAuth 令牌将从当前会话中删除。但是,如果该用户打开了另一个选项卡,则可以继续从该选项卡调用 (ReactJS) AJAX 回调,但最终将失败,因为不再有有效的令牌。

理想情况下,如果用户在回调期间不再被授权,将返回 401 响应,这会以某种方式触发浏览器重定向到 Flask 应用程序根目录(现在将检测到他们需要登录并重定向到用于登录的 OAuth 服务器)

在我的回调中,我可以包含类似于:

@dashapp.callback(
    Output('some-div', 'children'),
    Input('some-input', 'data')
    )
def my_fancy_callback(inputdata):
    if not session.get('token'):
      raise SessionExpiredException
    jsonResult = api.get('https://myapi.com/someinterestingdata')
    return jsonResult

然后有一个 Flask 错误处理程序来捕获这个特定的异常并返回一个 401 响应:

@app.errorhandler(SessionExpiredException)
def handle_SessionExpired_exception(e):
    return Response("Access Denied", 401)

这确实会导致 AJAX 调用返回 401 响应(如浏览器网络输出所示)。但是,我不确定如何在 React/Browser 方面挂钩这个调用?使用 Dash,我可以考虑添加一些自定义 JavaScript 文件,以某种方式在全局范围内拦截 XMLHttpRequest,但我想知道是否已经内置了对 Dash 的支持来完成此操作?

我对 Python/Flask/Dash/Plotly 非常陌生,所以如果有其他客户端错误处理的最佳实践,我会欢迎任何建议。

【问题讨论】:

    标签: python flask error-handling plotly


    【解决方案1】:

    在没有 Dash Enterprise 中间件的情况下,可以在 OAuth 后面保护 Flask 上的 Dash 应用程序,但设置它并不直观。我使用具有以下组件的应用程序工厂方法来保护 dash 应用程序。

    此模式将检查所有 Dash 布局和回调的身份验证状态,而无需任何特定的回调代码。

    my_dash_app = Dash(
        __name__,
        server=flask_server,
        url_base_pathname=f'/{base_pathname}/',
        assets_folder=assets_folder,
        meta_tags=[meta_viewport],
        external_stylesheets=external_stylesheets,
        suppress_callback_exceptions=True,
        external_scripts=external_scripts
    )
    protect_dash_views(my_dash_app)
    
    def protect_dash_views(my_dash_app):
        for view_func in my_dash_app.server.view_functions:
            if view_func.startswith(my_dash_app.config.url_base_pathname):
                my_dash_app.server.view_functions[view_func] = azure_authentication_required(
                    my_dash_app.server.view_functions[view_func])
    
    def azure_authentication_required(protected_function):
        @wraps(protected_function)
        def decorated_function(*args, **kwargs):
    
            if not user_is_employee():  # flask session cookie has expired, force user to login again.
                return redirect(url_for("login"))
    
            if user_is_blocked_from_access():
                return abort(403, 'You do not have permission to access This Application.')  # prevents further code execution.
    
            if azure_access_token_is_expired():
                user_id = get_azure_user_id()
                get_refresh_token_from_cache(user_id=user_id)  # this routine aborts code 403 if not successful.
    
            return protected_function(*args, **kwargs)
    
        return decorated_function
    

    【讨论】:

    • 这类似于我们现在所做的,它确实/确实可以保护 Flask 路由和回调。但是,如果用户已经加载了 dash 应用程序(React),然后在某个时候他们的会话过期,则回调会导致 401。在这种情况下,似乎不清楚如何在 React 端处理这个问题(客户端浏览器)。我相信重定向只会导致 AJAX 调用可能重定向,但实际上不会重定向主反应应用程序。我想这个问题也可以表述为“使用 Dash 时如何处理客户端 React 错误”
    猜你喜欢
    • 2018-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多