flask 项目之中实现跨域请求保护

1,对一个应用app开启一个保护,跨域请求针对的是所有的请求,包括get

from flask_wtf.csrf import CSRFProtect, generate_csrf
CSRFProtect(app)

2,浏览器发送请求,服务器给每次请求设置 csrf_token值

# 请求钩子,每次请求都会设置 csrf_token值,视图函数执行之后调用!
# 在每次请求之后, 生成csrf_token, 设置到cookie中,对响应进行最后的处理!
@app.after_request
def after_request(response):
    # token生成后,会缓存起来, 多次生成仍是同一个
    csrf_token = generate_csrf()
    # WTF扩展会自动将corf_token存入session
    response.set_cookie('csrf_token', csrf_token)
    return response

3,前端将cookie之中的csrf_token之中的设置到自己的请求之中
  如果ajax 来实现数据交互

$.ajax({
            url: "/user/base_info",
            type: "post",
            contentType: "application/json",
            headers: {
                "X-CSRFToken": getCookie("csrf_token")
            },
            data: JSON.stringify(params),
            success: function (resp) {
                if (resp.errno == "0") {
                    // 更新父窗口内容
                    $('.user_center_name', parent.document).html(params['nick_name'])
                    $('#nick_name', parent.document).html(params['nick_name'])
                    $('.input_sub').blur()
                } else {
                    alert(resp.errmsg)
                }
            }
        })

  如果是表单,可以是表单内任意一个标签设置csrf_token()

<form method="post" class="login_form">
        <h1 class="login_title">用户登录</h1>
        <input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
        <input type="text" name="username" placeholder="用户名" class="input_txt">
        <input type="password" name="password" placeholder="密码" class="input_txt">
        {% if errmsg %}
            <div class="error_tip" style="display: block">{{ errmsg }}</div>
        {% endif %}
        <input type="submit" value="登 录" class="input_sub">
</form>

4,后端收到请求之后会将csrf_token() 值进行比对,如果相同就可以认为不是钓鱼网站的请求!
  以下是'模拟'CSRFProtect 类的操作,在执行表单提交会进行以下操作。

'''
if request.method == "POST":
    to_account = request.form.get("to_account")
    money = request.form.get("money")
    # 取出表单中的 csrf_token
    form_csrf_token = request.form.get("csrf_token")
    # 取出 cookie 中的 csrf_token
    cookie_csrf_token = request.cookies.get("csrf_token")
    # 进行对比
    if cookie_csrf_token != form_csrf_token:
        return 'token校验失败,可能是非法操作'
    print('假装执行转操作,将当前登录用户的钱转账到指定账户')
    return '转账 %s 元到 %s 成功' % (money, to_account)

'''

 

posted @ 2018-06-06 19:38  十七楼的羊  阅读(176)  评论(0编辑  收藏  举报