Flask之安全地重定向回来

  表单处理的常见模式是自动重定向回用户。 通常有两种方法:检查下一个URL参数或查看HTTP引用者。

不幸的是,您还必须确保用户不会被重定向到恶意攻击者的页面,而只是重定向到同一主机。 如果您使用的是Flask-WTF,

那么有一种更好的方法:使用Flask-WTF重定向。确保重定向目标将指向同一服务器的函数位于:

 

Part1

from urllib.parse import urlparse,urljoin # python3
# python2 from
urlparse import urlparse, urljoin from flask import request, url_for def is_safe_url(target): ref_url = urlparse(request.host_url) test_url = urlparse(urljoin(request.host_url, target)) return test_url.scheme in ('http', 'https') and \ ref_url.netloc == test_url.netloc

 

 part2

使用它的一种简单方法是编写一个get_redirect_target函数,该函数查看各种提示以查找重定向目标:

 

 

def get_redirect_target():
    for target in request.values.get('next'), request.referrer:
        if not target:
            continue
        if is_safe_url(target):
            return target

 

 

part3

  由于我们不想重定向到同一页面,我们必须确保实际的后向重定向略有不同(仅使用提交的数据,而不是引用者)。 我们也可以在那里有一个后备:

def redirect_back(endpoint, **values):
    target = request.form['next']
    if not target or not is_safe_url(target):
        target = url_for(endpoint, **values)
    return redirect(target)

 

 

part4

  它将首先尝试使用next和referrer,然后回退到给定的端点。 然后,您可以在视图中使用它:

@app.route('/login', methods=['GET', 'POST'])
def login():
    next = get_redirect_target()
    if request.method == 'POST':
        # login code here
        return redirect_back('index')
    return render_template('index.html', next=next)

 

 

part5

  重要的是,如果所有提示都失败(在这种情况下是索引页面),我们就有一个重定向目标。
在模板中,您必须确保中继重定向目标:

<form action="" method=post>
  <dl>
    <dt>Username:
    <dd><input type=text name=username>
    <dt>Password:
    <dd><input type=password name=password>
  </dl>
  <p>
    <input type=submit value=Login>
    <input type=hidden value="{{ next or '' }}" name=next>
</form>

 

 

  或者就在这里使None成为一个空字符串。
Armin Ronacher的这个片段可以随意用于任何你喜欢的内容。 考虑它是公共领域。

 

posted @ 2019-04-12 18:22  Mr_Yun  阅读(584)  评论(0)    收藏  举报