使用Flask/WTForms和React进行CSRF保护 [英] CSRF Protection with Flask/WTForms and React
问题描述
对于通过React(作为受控组件)提交到Flask后端(理想情况下是使用WTForms)提交的表单,是否有人成功实现了CSRF保护?我已经看到了很多部分答案,其中一个是关于Django的答案,但是找不到任何适合Flask的东西.我的大问题似乎是我不知道如何将csrf令牌发送到我的react前端,在提交表单之前将其存储为标头,然后使用正确的令牌提交表单.任何方向都会很有帮助.
Has anyone successfully implemented CSRF protection for a form submitted with React (as a controlled component) to a Flask back-end (ideally with WTForms)? I've seen a lot of partial answers, and one with Django, but couldn't find anything definitive for Flask. My big issue seems to be that I don't know how to send the csrf token to my react front end, store it as a header before submitting my form, then submit my form with the correct token. Any direction would be really helpful.
推荐答案
所以,基本上,我所做的是我在Flask中设置了一条可以接收GET和POST请求的路由.当组件挂载时,React发送一个GET请求,并且Flask以csrf令牌作为头响应(手动完成).然后React将这个值存储在状态中.提交表单后,来自state的csrf令牌将作为字段发送,类似于在纯Flask应用程序中将其发送为隐藏字段的方式.尽管从技术上讲这是可行的,但我很好奇它是否仍然容易受到CSRF的攻击.我认为第二个最佳选择是在所有端点上设置CSRF保护,因此,如果这不安全,可以尝试一下.
So, essentially what I did is I set up a route in Flask that can receive both GET and POST requests. React sends a GET request when the component mounts, and Flask responds with the csrf token as a header (done manually). Then React stores this value in state. When the form is submitted, the csrf token from state is sent as a field, similar to the way it is sent in a pure Flask app, where it would be a hidden field. While this technically works, I am curious if this is still vulnerable to CSRF. I think the next best option is to set up CSRF protection on all endpoints, so can try that if this isn't secure.
烧瓶路线:
@app.route('/api/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
print(request.method)
if request.method == 'GET':
return ('', {'csrf_token': form.csrf_token._value()})
elif form.validate_on_submit():
return { 'message': 'Login successful' }, 200
else:
return { 'errors': form.errors }
在componentDidMount中获取请求:
GET request in componentDidMount:
componentDidMount() {
axios.get('/api/login',{data: null, headers: {'Content-Type': 'application/json'}})
.then(res => {
console.log(res)
this.setState({
csrf: res.headers.csrf_token
});
})
}
提交表单后的POST请求:
POST request when form is submitted:
onSubmitLogin = e => {
e.preventDefault();
const userData = {
username: this.state.username,
password: this.state.password,
csrf_token: this.state.csrf
};
axios({
method: 'post',
url: '/api/login',
data: userData,
headers: {
'content-type': 'application/json'
}
})
.then(res => {
console.log(res);
});
}
这篇关于使用Flask/WTForms和React进行CSRF保护的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!