python - 如何覆盖 Flask 蓝图 URL?

标签 python oauth flask mediawiki-extensions

我正在使用 flask-mwoauth在 Mediawiki(尤其是维基百科)上使用 OAuth 身份验证在 Flask 中创建一个简单的应用程序。

flask-mwoauth 是一个蓝图,它提供了一些与 Mediawiki Extensions:OAuth 交互的便捷方法,并添加了以下 URI:

  • /login - 运行 OAuth 握手并将用户返回到 /
    • /login?next=/someurl 会将用户返回到 /someurl
  • /logout - 清除用户的访问 token
    • /logout?next=/someurl 会将用户返回到 /someurl
  • /oauth-callback - 从 MW 回调以完成握手

用户的 OAuth key 和 secret 存储在 session 中。

我希望能够为其中一些自定义 URI 创建自定义响应。以/logout为例,响应的定义非常简单(__init__.py#L56):

@self.bp.route('/logout')
def logout():
    session['mwo_token'] = None
    session['username'] = None
    if 'next' in request.args:
        return redirect(request.args['next'])
    return "Logged out!"

我想在我的应用程序中定义带有自定义响应(例如,呈现模板)的路由 /logout,但是如果我使用蓝图,那么路由 @app. route("/logout") 被忽略。

我想知道是否可以在我的应用程序中定义路由 /logout 的意义上“扩展”蓝图,从蓝图中调用原始方法,然后提供定制的响应。

最佳答案

如果你想完全重新定义路由的行为,最好的方法是覆盖 MWOAuth 类。这是一个有效的例子:

import os

from flask import Flask, Blueprint
from flask_mwoauth import MWOAuth

app = Flask(__name__)
app.secret_key = os.urandom(24)


class MyMWOAuth(MWOAuth):
    def __init__(self,
                 base_url='https://www.mediawiki.org/w',
                 clean_url="Deprecated",
                 default_return_to='index',
                 consumer_key=None,
                 consumer_secret=None,
                 name="Deprecated"):
        # I skipped other rows. It's just an example
        self.bp = Blueprint('mwoauth', __name__)
        # By the way you can customize here login and oauth-callback
        @self.bp.route('/logout')
        def logout():
            # your custom logic here...
            return "My custom logout"


mwoauth = MyMWOAuth(consumer_key='test', consumer_secret='test')
app.register_blueprint(mwoauth.bp)


if __name__ == "__main__":
    app.run(debug=True, threaded=True)

让我们打开/logout。您将看到 我的自定义注销。 如您所见,BluePrint 路由的注册发生在 MWOAuthinit 方法中。

第二种方式是使用request callbacks .这里有一个示例,演示了注销后响应正文的变化。

from flask import g, request


def after_this_request(f):
    if not hasattr(g, 'after_request_callbacks'):
        g.after_request_callbacks = []
    g.after_request_callbacks.append(f)
    return f


@app.after_request
def call_after_request_callbacks(r):
    for callback in getattr(g, 'after_request_callbacks', ()):
        callback(r)
    return r


@app.before_request
def before_logout():
    @after_this_request
    def after_logout(response):
        # check if called route == '/logout'
        # in our case response.data == 'Logged out!'
        # see: https://github.com/valhallasw/flask-mwoauth/blob/master/flask_mwoauth/__init__.py#L48
        if request.url_rule.endpoint == 'mwoauth.logout':
            # custom logic here...
            # for example I change data in request
            response.data = 'Data from after_logout'

让我们打开/logout。您将看到 来自 after_logout 的数据

希望这对您有所帮助。

关于python - 如何覆盖 Flask 蓝图 URL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38284424/

相关文章:

用于验证字典值中项目是否存在的 Python3 单行代码

python - Flask-WTForms 更改提交的日期字段值

python - Instagram 和 oAuth

javascript - Node JS Passport Google OAuth 未进行身份验证

python - beautifulsoup 解析 - 处理上标?

python - 为什么在 Python 中嵌套类的意外命名?如何 "fix"?

laravel - 更改 Laravel Passport/OAuth 服务器响应

python - Flask 无法识别两个 URL 参数

python - 运行AWS Deep Learning Base AMI(Amazon Linux 2)时如何在Elastic Beanstalk中设置WSGI?

python - 无法使用 REST API 调用访问/下载 Docker 容器内生成的文件夹