feat(api): 新增 CSRF 校验

This commit is contained in:
不胜舟
2025-09-02 11:37:27 +08:00
parent 000330dbd7
commit 5bcc28a492
5 changed files with 20 additions and 2 deletions
+5 -1
View File
@@ -10,6 +10,10 @@ def init_error_views(app):
def page_not_found(e): def page_not_found(e):
return render_template('errors/404.html'), 404 return render_template('errors/404.html'), 404
@app.errorhandler(405)
def page_not_found(e):
return render_template('errors/404.html'), 404
@app.errorhandler(500) @app.errorhandler(500)
def internal_server_error(e): def internal_server_error(e):
return render_template('errors/500.html'), 500 return render_template('errors/500.html'), 500
@@ -18,4 +22,4 @@ def init_error_views(app):
def ratelimit_exceeded(e): def ratelimit_exceeded(e):
return jsonify( return jsonify(
success=False, msg="请求频率超限,请稍后再试。" success=False, msg="请求频率超限,请稍后再试。"
) )
@@ -1,5 +1,6 @@
from flask import session, current_app from flask import session, current_app
from flask_login import current_user from flask_login import current_user
from flask_wtf.csrf import generate_csrf
def init_template_directives(app): def init_template_directives(app):
@@ -9,3 +10,8 @@ def init_template_directives(app):
return bool(power in session.get('permissions')) return bool(power in session.get('permissions'))
else: else:
return True return True
@app.template_global()
def csrf_input():
return f'<input type="hidden" name="csrf_token" value="{generate_csrf()}">'
+7 -1
View File
@@ -1,4 +1,6 @@
from flask import Blueprint, render_template, request, jsonify from flask import Blueprint, render_template, request, jsonify
from flask_wtf.csrf import validate_csrf
from wtforms.validators import ValidationError
from applications.common import curd from applications.common import curd
from applications.common.helper import ModelFilter from applications.common.helper import ModelFilter
@@ -49,7 +51,10 @@ def dict_type_add():
@authorize("system:dict:add", log=True) @authorize("system:dict:add", log=True)
def dict_type_save(): def dict_type_save():
req_json = request.get_json(force=True) req_json = request.get_json(force=True)
try:
validate_csrf(req_json.get("csrf_token"))
except ValidationError:
return fail_api(msg='非法请求')
data = { data = {
'type_name': str_escape(req_json.get("typeName")), 'type_name': str_escape(req_json.get("typeName")),
'type_code': str_escape(req_json.get("typeCode")), 'type_code': str_escape(req_json.get("typeCode")),
@@ -180,6 +185,7 @@ def dict_data_add():
def dict_data_save(): def dict_data_save():
req_json = request.get_json(force=True) req_json = request.get_json(force=True)
data_label = str_escape(req_json.get("dataLabel")) data_label = str_escape(req_json.get("dataLabel"))
data_value = str_escape(req_json.get("dataValue")) data_value = str_escape(req_json.get("dataValue"))
enable = str_escape(req_json.get("enable")) enable = str_escape(req_json.get("enable"))
+1
View File
@@ -8,6 +8,7 @@ cryptography==41.0.2
decorator==5.1.1 decorator==5.1.1
Flask==2.3.2 Flask==2.3.2
Flask-APScheduler==1.12.4 Flask-APScheduler==1.12.4
Flask-Limiter==3.12
Flask-Login==0.6.2 Flask-Login==0.6.2
Flask-Mail==0.9.1 Flask-Mail==0.9.1
flask-marshmallow==0.15.0 flask-marshmallow==0.15.0
+1
View File
@@ -9,6 +9,7 @@
<div class="mainBox"> <div class="mainBox">
<div class="main-container"> <div class="main-container">
<div class="main-container"> <div class="main-container">
{{ csrf_input()|safe }}
<div class="layui-form-item"> <div class="layui-form-item">
<label class="layui-form-label">名称</label> <label class="layui-form-label">名称</label>
<div class="layui-input-block"> <div class="layui-input-block">