CSRF Protection with Flask/WTForms and React

☆樱花仙子☆ 提交于 2021-02-10 18:10:35

问题


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.


回答1:


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.

Flask route:

@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 }

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 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);
  });
}



回答2:


Maybe you need flask-security-too lib https://flask-security-too.readthedocs.io/en/stable/patterns.html#csrf



来源:https://stackoverflow.com/questions/62249834/csrf-protection-with-flask-wtforms-and-react

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!