I have a Python Flask server serving not only an webapp but also a set of routes, sort of like an API.
In this webapp, I\'m using only ReactJS, as in the HTML code is s
My suggestion is to pass data using Jinja2 templates. It could be anything (e.g. <meta>
tags or even a hidden <div>
), but I would suggest a <script>
tag with initial data. E.g. something in spirit of
...
<script type="text/javascript">
window.initialData = {{ initial_data|tojson }};
</script>
<script type="text/javascript" src="assets/your-react-app/main.js"></script>
</body>
</html>
Where initial_data
contains all your React app need to know, e.g. username, profile picture URL, new notifications flag, etc.
This data is only for React app to know what server thinks of you. I.e. showing a login page if you aren't logged in, or greeting the user correctly. As long as both JS and HTML (template) code is under your control, this is as secure as rendering a static page with this information. As there are no issues with rendering "You're logged in as {{ current_user.username }}
", neither there are with those. Of course, any user can change this - by editing HTML or JS respectively - but this is would be a purely cosmetic, client-side-only hack.
An alternative would be to implement some API endpoints, e.g. /api/whoami
and query those on React app initialization. The upside is, you don't need any templating (your HTML can be completely static), the downside is, you need to send an extra HTTP request and wait for response before you can show end-user the final page. From the security viewpoint, it's essentially the same as the JS-in-HTML method above, just that the transport differs.
Actually, normally it's both approaches mixed. Embedding is to avoid extra round-trip on the first page load, and API is to get updates after your app believes the state should've changed (e.g. after user presses the "logout" button).
When you're sending requests to your server (form submissions, XHR/AJAX API requests or anything else that takes user into account), never trust the client input and don't even send to the server who you think you are - but check what the session says. This means you have to make sure to pass cookies around, e.g. with fetch
you need fetch(url, {credentials: "same-origin"})
for the request to have cookies.
Basically, pass the data React has to know as JSON documents (via template embedding or API endpoint response), and don't let server do anything wrong if that data is modified.