5

I am building a website and along the way I have come across a lot of things I didn't know about and was hoping to get some help in understanding some of them.

I started building a website using Flask and the Jinja templating language. This was very intuitive and easy to understand: client makes a request, server checks all requests are good and then delivers the whole working page in one go.

Then I wanted to upgrade my frontend to use ReactJS. From my research I found that I could still go the server-side rendering route if I used a library like python-react, but I opted for client-side rendering instead. This meant a couple of things

  • I will need a frontend server (e.g. node.js) to render the frontend
  • I will need to refactor my Flask backend to behave like an API

So when a client makes a request for, say, the home page, the process will look something like this (if I understand correctly?): enter image description here

Assuming I am correct up to this point, my question is, how does the above diagram look in the case of submitting a form?

A form requires a CSRF token to be embedded in it when it is rendered, i.e. the token is created on the Frontend Server. But then, how does the Backend verify that token? Does all authentication also need to happen on the Frontend server? I am not clear on how the Frontend and Backend fit together.

turnip
  • 1,657
  • 2
  • 15
  • 21
  • Hence why I am asking the question... at the time of writing I thought ReactJS can only be ran with NodeJS. Now I know that that isn't the case. – turnip Dec 12 '18 at 14:50
  • "but I opted for client-side rendering instead. This meant a couple of things ... I will need a frontend server (e.g. node.js) to render the frontend". This seems contradictory. If you are opting for *client-side* __rendering__, why would you need a *server* for __rendering__? – JimmyJames Dec 12 '18 at 16:42

2 Answers2

10

You are incorrect about the need for separate front-end and back-end servers. You need only one server, which can be your Flask-based server, that

  • provides one (static) HTML page when users access the entry-point URL (/home in your diagram)
  • provides a bunch of (static) JS files for the ReactJS implementation of your front-end
  • provides an API for the dynamic content of the site.

As there is only one server, the handling of the CSRF tokens shouldn't be an issue.

Bart van Ingen Schenau
  • 71,712
  • 20
  • 110
  • 179
  • I thought about this but I don't get how I would "embed" the CSRF token with Flask into a ReactJS form? – turnip Dec 10 '18 at 15:23
  • @turnip Your API would offer an endpoint that returns a new token. Then your React-based frontend can get a token from this endpoint before submitting the form. – amon Dec 10 '18 at 15:48
  • @amon I see. Is this standard practice? – turnip Dec 10 '18 at 16:32
  • What's standard practice or not is hard to say these days with so many approaches possibles. However, it's convenient if there's only one server. Since the API is responsible for the form intake, I would expect the same API to manage and handle the CSRF tokens. – Laiv Dec 12 '18 at 14:50
1

For the CSRF concerns in an API using Flask you can use one of the plugins such as SeasSurf. Basically the CSRF token will be created on the back-end server and then stored in the client via a cookie that is passed on responses from that server. Then the csrf values are passed and verified in your Post requests to the back-end server within the request header.

Turnkey
  • 1,697
  • 9
  • 10