NagariaHussain / doppio

A Frappe app (CLI) to magically setup single page applications and Vue/React powered desk pages on your custom Frappe apps.
MIT License
202 stars 77 forks source link

Vue.js SPA issue with CSRF_token when app is deployed on frappe cloud #39

Open sduenasg opened 2 months ago

sduenasg commented 2 months ago

We are using Frappe 15.41.0. Used doppio to create a SPA (vue.js) that calls the Frappe backend with GET and POST calls. When the site is deployed to frappe cloud, this SPA gets CSRF_TOKEN errors on the POST API calls. This is easily triggered by navigating from the desk to the SPA or back and triggering these calls.

We have disabled CSRF_token verification on the site's config, and then everything works fine, but it is a security issue for a site that is in production. Users log in on Frappe's login screen, we don't have a login page on the SPA, since the experience between the desk and SPA must be seamless. On the desk, we have a workspace with a Shortcut to the SPA (/spaname), and from the SPA, there is a link to go to the desk (/app).

For the api calls we tried

1- fetch, with these headers

const log_header ={
                'X-Frappe-Site-Name': window.location.hostname,
                'X-Frappe-CSRF-Token': window.csrf_token,
                'Content-Type': 'application/json'
              }

2 doppio's call function, same issue

3 axios, same issue

Same issues with all three. Our index.hml:

image

On our local dev environment (docker) this does not happen that often. Sometimes seems to happen tho (by using the built site, not yarn dev), we do not have disabled csrf_token verification on our dev environments.

Anyone know what's going on? Thank you.

sduenasg commented 2 months ago

Disabling website cache on the production site (Frappe Cloud) seems to have fixed this... we'll do more thorough testing today

image

The solution is not ideal though, cache is important too.

I'm not sure if i should report this to Frappe repo instead of here. Maybe the issue is not doppio?

Since we managed to replicate the issue in our local environments (enable cache), i added prints to frappe's auth.py csrf_token validation, and as you can see, the CSRF_token that we receive from the client is null

image

Then, when I disable cache, the token arrives

image

Issue seems to be that

<script>window.csrf_token = '{{ frappe.session.csrf_token }}';</script>

is not runing when the SPA is loaded from cache, and window.csrf_token looses its value.