flask csrf

在flask中开启csrf保护

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

1
2
from flask_wtf.csrf import CsrfProtect
CsrfProtect(app)

csrf也支持惰性加载

1
2
3
4
5
6
from flask_wtf.csrf import CsrfProtect
csrf = CsrfProtect()

def create_app():
app = Flask(__name__)
csrf.init_app(app)

配置

  • app.config[“SECRET_KEY”]:csrf保护需要app设置盐
  • app.config[“WTF_CSRF_CHECK_DEFAULT”] 为 False:在所有的视图中禁用CSRF保护

视图单独配置

当全局开启 csrf 时,可选择部分视图关闭

FBV 关闭 (基于函数的视图)

如果你想要某些路由不进行csrf验证,使用csrf.exempt放弃验证

1
2
3
4
@csrf.exempt
@app.route('/foo', methods=('GET', 'POST'))
def my_handler():
return 'ok'

CBV 关闭 (基于类的视图)

1
2
3
4
5
6
7
class IndexView(views.View):
methods = ['GET'] # 允许的method
decorators = [csrf.exempt] # 装饰器,把放弃验证的装饰器写到这里
def dispatch_request(self):
print('Index')
return 'Index!'
app.add_url_rule('/index', view_func=IndexView.as_view(name='index'))

当全局关闭 csrf 时,可选择部分视图开启

FBV 关闭 (基于函数的视图)

默认情况下也可以在所有的视图中禁用 CSRF 保护,通过设置 WTF_CSRF_CHECK_DEFAULT 为 False,仅仅当需要的时候选择调用 csrf.protect()。这也能够在检查 CSRF 令牌前做一些预先处理

1
2
3
4
5
6
7
@app.before_request
def check_csrf():
if not is_oauth(request):
csrf.protect()
```

#### CBV 关闭 (基于类的视图)

class IndexView(views.View):
methods = [‘GET’] # 允许的method
decorators = [csrf.protect] # 装饰器,把放弃验证的装饰器写到这里
def dispatch_request(self):
print(‘Index’)
return ‘Index!’
app.add_url_rule(‘/index’, view_func=IndexView.as_view(name=’index’))

1
2
3
4

## 页面添加csrf

在表单中添加csrf验证

方式一:

方式二:(推荐)

注:因为hexo 的某些原因,value 的值应该是 csrf_token(), 为了防止冲突,下面写的是 csrf_token,

1
2
3
4

不用表单,通过ajax发送post请求成为可能,flask 0.9后的版本可用。如果你使用了 CsrfProtect(app),你可以通过 {{ csrf_token() }} 获取 CSRF 令牌。这个方法在每个模板中都可以使用,你并不需要担心在没有表单时如何渲染 CSRF 令牌字段。

官方推荐在<meta>标签中渲染CSRF令牌:
# 注:因为hexo 的某些原因,content 的值应该是 csrf_token(), 为了防止冲突,下面写的是 csrf_token,
1
2

<script>标签中渲染同样可以:
# 注:因为hexo 的某些原因,csrftoken 的值应该是 csrf_token(), 为了防止冲突,下面写的是 csrf_token,
1
2
3
4
5


## csrf不通过会返回400响应

你可以自定义返回的页面
@csrf.error_handler def csrf_error(reason): return render_template('csrf_error.html', reason=reason), 400
1
2
3
4
5
6
7


## 提交带csrf的请求请求

无论什么时候发送 Ajax POST 请求,都要添加X-CSRFToken请求头

### AJAX 方法一:
# 首先在html文件里面的head标签里面添加meta标签 # 注:因为hexo 的某些原因,content 的值应该是 csrf_token(), 为了防止冲突,下面写的是 csrf_token,

然后在script里面使用jquery获取

1
2

### AJAX 方法二:


flask csrf
https://flepeng.github.io/021-Python-32-框架-Flask-03-Flask-csrf/
作者
Lepeng
发布于
2021年3月31日
许可协议