正确获取和设置 csrf 令牌
Fetching and setting the csrf token correctly
我正在尝试创建一个使用 flask_cors
和 flask_wtf
的简单应用程序。然而,当我使用 flask_wtf
时,当我尝试发送 POST 请求时,我收到一个回复说 CSRF 令牌丢失。
这是我的 back-end 应用程序(运行 在端口 3080 上):
__init__.py
from flask import Flask
from flask_cors import CORS
from flask_wtf.csrf import CSRFProtect
cors = CORS()
csrf = CSRFProtect()
def create_app(config):
app = Flask(__name__, instance_relative_config=False)
app.config['TESTING'] = True
app.config['DEBUG'] = True
app.config['JSON_SORT_KEYS'] = False
app.config['SECRET_KEY'] = 'You will never guess me!'
app.config['SESSION_COOKIE_HTTPONLY']= True
app.config['REMEMBER_COOKIE_HTTPONLY'] = True
app.config['SESSION_COOKIE_SAMESITE'] = 'Strict'
cors.init_app(app)
csrf.init_app(app)
with app.app_context():
from app.views.sanity_bp import sanity_bp
app.register_blueprint(sanity_bp, url_prefix='/api/sanity')
return app
sanity_bp.py
from flask import Blueprint, jsonify, request
from flask_cors import cross_origin
from flask_wtf.csrf import generate_csrf
sanity_bp = Blueprint('sanity_bp', __name__)
@sanity_bp.route('/get/csrf', methods=['GET'])
def get_csrf():
return jsonify({'csrf_token': generate_csrf()}), 200
@sanity_bp.route('/post', methods=['POST'])
@cross_origin()
def post():
return jsonify('sanity: post request'), 200
这里我使用get_csrf()
方法获取CSRF token。
前端(运行在8080端口)给出如下:
<template>
<div>
Hello stack <b>overflow</b>!
</div>
</template>
<script>
import axios from 'axios';
const API = axios.create({
baseURL: 'http://127.0.0.1:3080/api',
});
const csrf = () => {
API
.get('/sanity/get/csrf', { credentials: 'same-origin' })
.then((res) => {
API.defaults.headers.post['x-csrf-token'] = res.data.csrf_token;
})
.catch((err) => {
console.log('err = ', err);
});
};
export default {
name: 'app',
methods: {
sanity() {
API
.post('/sanity/post', { message: 'ping' })
.then((res) => {
console.log('res.data = ', res.data);
})
.catch((error) => {
console.error('error = ', error);
});
},
},
created() {
csrf();
this.sanity();
},
};
</script>
因此,当调用 created()
方法时,我从后端获取 CSRF 令牌并将其设置为 [=19= 的 header 中的 x-csrf-token
值] 函数。
但是,当我在 sanity()
方法中使用 POST 请求时,我收到 400 错误,指出未设置 CSRF 令牌。此外,x-csrf-token
键在请求 header 中不可见。为什么不呢,请问我获取令牌哪里出错了?
你在前端的csrf
函数是异步的,你需要等到它完成后再在created
函数中制作this.sanity();
。您可以使用 async/await
...
async created() {
await csrf();
await this.sanity();
},
...
我正在尝试创建一个使用 flask_cors
和 flask_wtf
的简单应用程序。然而,当我使用 flask_wtf
时,当我尝试发送 POST 请求时,我收到一个回复说 CSRF 令牌丢失。
这是我的 back-end 应用程序(运行 在端口 3080 上):
__init__.py
from flask import Flask
from flask_cors import CORS
from flask_wtf.csrf import CSRFProtect
cors = CORS()
csrf = CSRFProtect()
def create_app(config):
app = Flask(__name__, instance_relative_config=False)
app.config['TESTING'] = True
app.config['DEBUG'] = True
app.config['JSON_SORT_KEYS'] = False
app.config['SECRET_KEY'] = 'You will never guess me!'
app.config['SESSION_COOKIE_HTTPONLY']= True
app.config['REMEMBER_COOKIE_HTTPONLY'] = True
app.config['SESSION_COOKIE_SAMESITE'] = 'Strict'
cors.init_app(app)
csrf.init_app(app)
with app.app_context():
from app.views.sanity_bp import sanity_bp
app.register_blueprint(sanity_bp, url_prefix='/api/sanity')
return app
sanity_bp.py
from flask import Blueprint, jsonify, request
from flask_cors import cross_origin
from flask_wtf.csrf import generate_csrf
sanity_bp = Blueprint('sanity_bp', __name__)
@sanity_bp.route('/get/csrf', methods=['GET'])
def get_csrf():
return jsonify({'csrf_token': generate_csrf()}), 200
@sanity_bp.route('/post', methods=['POST'])
@cross_origin()
def post():
return jsonify('sanity: post request'), 200
这里我使用get_csrf()
方法获取CSRF token。
前端(运行在8080端口)给出如下:
<template>
<div>
Hello stack <b>overflow</b>!
</div>
</template>
<script>
import axios from 'axios';
const API = axios.create({
baseURL: 'http://127.0.0.1:3080/api',
});
const csrf = () => {
API
.get('/sanity/get/csrf', { credentials: 'same-origin' })
.then((res) => {
API.defaults.headers.post['x-csrf-token'] = res.data.csrf_token;
})
.catch((err) => {
console.log('err = ', err);
});
};
export default {
name: 'app',
methods: {
sanity() {
API
.post('/sanity/post', { message: 'ping' })
.then((res) => {
console.log('res.data = ', res.data);
})
.catch((error) => {
console.error('error = ', error);
});
},
},
created() {
csrf();
this.sanity();
},
};
</script>
因此,当调用 created()
方法时,我从后端获取 CSRF 令牌并将其设置为 [=19= 的 header 中的 x-csrf-token
值] 函数。
但是,当我在 sanity()
方法中使用 POST 请求时,我收到 400 错误,指出未设置 CSRF 令牌。此外,x-csrf-token
键在请求 header 中不可见。为什么不呢,请问我获取令牌哪里出错了?
你在前端的csrf
函数是异步的,你需要等到它完成后再在created
函数中制作this.sanity();
。您可以使用 async/await
...
async created() {
await csrf();
await this.sanity();
},
...