如何覆盖 Flask 蓝图 URL?
How to override a Flask blueprint URL?
我正在使用 flask-mwoauth
在 Mediawiki(尤其是维基百科)上使用 OAuth 身份验证在 Flask 中创建一个简单的应用程序。
flask-mwoauth
是一个蓝图,它提供了一些与 Mediawiki Extensions:OAuth 交互的便捷方法,并添加了以下 URI:
/login
- 运行 OAuth 握手并 return 将用户发送到 /
/login?next=/someurl
将 return 用户 /someurl
/logout
- 清除用户的访问令牌
/logout?next=/someurl
将 return 用户 /someurl
/oauth-callback
- MW 回调完成握手
用户的 OAuth 密钥和机密存储在会话中。
我希望能够为其中一些自定义 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")
将被忽略。
我想知道是否可以 "extend" 蓝图,因为我可以在我的应用程序中定义路由 /logout
,从蓝图中调用原始方法,然后提供自定义响应。
如果你想完全重新定义路由的行为,最好的方法是覆盖 MWOAuth
class。这是一个有效的例子:
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
。你会看到 My custom logout
。
如您所见,BluePrint 路由的注册发生在 MWOAuth
的 init
方法中。
第二种方法是使用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
。你会看到 Data from after_logout
。
希望对您有所帮助。
我正在使用 flask-mwoauth
在 Mediawiki(尤其是维基百科)上使用 OAuth 身份验证在 Flask 中创建一个简单的应用程序。
flask-mwoauth
是一个蓝图,它提供了一些与 Mediawiki Extensions:OAuth 交互的便捷方法,并添加了以下 URI:
/login
- 运行 OAuth 握手并 return 将用户发送到/
/login?next=/someurl
将 return 用户/someurl
/logout
- 清除用户的访问令牌/logout?next=/someurl
将 return 用户/someurl
/oauth-callback
- MW 回调完成握手
用户的 OAuth 密钥和机密存储在会话中。
我希望能够为其中一些自定义 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")
将被忽略。
我想知道是否可以 "extend" 蓝图,因为我可以在我的应用程序中定义路由 /logout
,从蓝图中调用原始方法,然后提供自定义响应。
如果你想完全重新定义路由的行为,最好的方法是覆盖 MWOAuth
class。这是一个有效的例子:
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
。你会看到 My custom logout
。
如您所见,BluePrint 路由的注册发生在 MWOAuth
的 init
方法中。
第二种方法是使用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
。你会看到 Data from after_logout
。
希望对您有所帮助。