Flask框架7(记录上一界面与url安全验证)

记录上一界面与url安全验证

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
flask重定向返回上一页方法
    方法一:
        导入:from flask import request
        使用:request.referrer==》记录访问来源即上一个请求地址
    方法二:
        使用:request.full_path ==》 获取当前页面完整路径
        在请求地址中传入?next=当前页面完整路径==》http://127.0.0.1:5000/some?next=/chn?
        重定向中使用request.args.get('next')==》 获取上一界面地址
flask之url安全认证
    原因:如果不验证会有【开放重定向漏洞】
    解决办法:is_safe_url()方法
"""

from flask import Flask
from flask import url_for
from flask import redirect
from flask import request
from urllib.parse import urlparse, urljoin

app = Flask(__name__)


def redirect_back(default='hello', **kwargs):
    """
    覆盖方式一与方式二方法
    :param default:
    :param kwargs:
    :return:
    """
    for target in request.args.get('next'), request.referrer:
        if not target:
            continue
        if is_safe_url(target):
            return redirect(target)
    return redirect(url_for(default, **kwargs))

def is_safe_url(target):
    ref_url = urlparse(request.host_url)  # 获取程序内的主机url
    test_url = urlparse(urljoin(request.host_url, target))  # 将目标URl转换为绝对路径
    return test_url.scheme in ('http', 'https') and ref_url.netloc == test_url.netloc  # 验证是否属于内部url


@app.route('/foo')
def foo():
    """
    方式一
    需要重定向回界面一"""
    return '<h1>Foo page</h1><a href="{}">do some</a>'.format(url_for("do_some"))


@app.route('/bar')
def bar():
    """
    方式一
    需要重定向回界面二"""
    return '<h1>bar page</h1><a href="{}">do some</a>'.format(url_for("do_some"))

@app.route('/chn')
def chn():
    """
    方式二
    需要重定向回界面三"""
    url = request.full_path
    return '<h1>chn page</h1><a href="{}?next={}">do some</a>'.format(url_for("some"), url)

@app.route('/fss')
def fss():
    """
    方式三
    需要重定向回界面三"""
    return '<h1>fss page</h1><a href="{}">do some</a>'.format(url_for("do_some_and_redirect"))

@app.route('/do_some_and_redirect')
def do_some_and_redirect():
    return redirect_back()

@app.route('/some')
def some():
    """方式二"""
    return redirect(request.args.get('next', url_for("hello")))


@app.route('/do_some')
def do_some():
    """方式一"""
    return redirect(request.referrer or url_for("hello"))


@app.route('/hi')
def hello():
    """默认地址"""
    return '<h1>hello</h1>'


if __name__ == '__main__':
    app.run()

 

posted @ 2019-03-20 09:15  争-渡  阅读(261)  评论(0)    收藏  举报