• 周二. 9月 27th, 2022

5G编程聚合网

5G时代下一个聚合的编程学习网

热门标签

Flask之CSRF

admin

11月 28, 2021

Flask之CSRF

一、什么是CSRF

CSRF跨站请求伪造,源于WEB的隐式身份验证机制,WEB的身份验证机制虽然可以抱着一个请求时来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的。

例如,用户登录受信任的网址A,在本地生成了Cookie,在Cookie没有失效的情况下去访问了危险网站B,B可能会盗用你的身份,以你的名义去发送恶意请求,邮件,盗取你的账号,设置购买商品,造成你个人隐私泄露,已经财产安全。

二、flask中CSRF保护

为了能够让所有的视图受到CSRF保护,需要扩展 CsrfProtect模块

from flask_wtf.csrf import CsrfProtect

from flask_wtf.csrf import CSRFProtect
from flask import Flask

app = Flask(__name__) # 生成Flask对象app
# 1.第一种写法
CSRFProtect(app) # 为Flask程序提供CSRF保护

# 2.第二种写法
csrf = CSRFProtect()
csrf.init_app(app) # 初始化CSRF保护的app

注意,需要为CSRF保护设置一个密钥,但通常情况下,和Flask应用的SECRET_KEY是一样的。

# 第一种写法,直接设置参数
app.config["SECRET_KEY"] = xcax[email protected]]x1bxd7"[email protected]#\'

# 第二种写法
class FlaskSetting:
    "SECRET_KEY" = [email protected]]x1bxd7"[email protected]#\'
app.config.from_object(FlaskSetting)

如果你设置的模板中存在表单,你只需要在表单中添加如下

<form method="post" action="/">
    {{ form.csrf_token }}
</form>

如果没有模板中没有表单,你仍然需要一个 CSRF 令牌:

<form method="post" action="/">
    <input type="hidden" name="csrf_token" value="{{ csrf_token() }}" />
</form>

如果不使用表单,使用AJAX交互数据:

需要在前端的AJAX添加请求头 headers: { “X-CSRFToken”: csrfToken } ;否则会出现 statecode:400的状态码,csrf_token miss的错误。

# 前端
<div>
        <form action="/register" method="POST" class="col-md-4 col-md-offset-4"
              data-need_bind_qywx="{{ need_bind_qywx }}" id="register_form">
            <h2 class="align-center">注册</h2>
            {{ form.csrf_token }}
            {% for item in form %}
                {% if item != form.csrf_token %}
                    {% if item == form.email_code %}
                        <p>{{item.label}}:</p>
                        <div class="row">
                            <div class="col-xs-8">
                                {{ item }}
                                {{item.errors[0]}}
                            </div>
                            <div class="col-xs-4">
                                <input id="get-email-code" type="button" value="点击获取验证码">
                            </div>
                        </div>
                    {% else %}
                        <p>{{item.label}}:{{item}}{{item.errors[0]}}</p>
                    {% endif %}
                {% endif %}
            {% endfor %}
            <a href="/login">已有账号登录</a>
            <div><input type="submit" value="注册"></div>
        </form>
        <div id="qiye-wechat"></div>
    </div>
    <script>
        $(document).ready(function () {
            $('#get-email-code').click(function () {
                const csrfToken = document.getElementById('csrf_token').value;
                $.ajax({
                    url: '/register/get_email_code',
                    type: 'post',
                    headers: {
                        "X-CSRFToken": csrfToken
                    },
                    data: JSON.stringify({
                        email: $('input[name="email"]').val()
                    }),
                    contentType: 'application/json',
                    success: function (result) {
                        alert(result.message)
                    }
                });
            });
        });
    </script>

发表回复

您的电子邮箱地址不会被公开。