I have a Softr app that embeds a Superset Dashboard and an n8n AI Chat bubble. Currently, I’m using custom code blocks to fetch Guest Tokens using the user’s email (window.logged_in_user.softr_user_email).
As my app scales, this is no longer secure. Any user can open the browser console, change their email variable, and potentially “spoof” their identity to see another client’s data. Furthermore, my Superset IDs and RLS logic are visible in the frontend script.
My Ideal Architecture: I want to move all logic to a “Middle-Man” API (Node/Python) that sits between Softr and my Postgres DB.
Questions for the Softr Experts:
Secure Handshake: How are you passing a “proof of identity” from Softr to an external API that isn’t just a plain-text email?
Hidden Constants: Since Softr Custom Code is always public, how do you trigger sensitive fetches without exposing the logic to the “Inspect Element” tool?
Session Tokens: Has anyone successfully used a “one-time-use” token generated in Airtable/Postgres that expires after the Superset dashboard is loaded?
BUT, you can fetch the users jwtToken from the browser, send that up with your request, and verify it’s valid with the softr API in the middleware. This will also tell you the email of the verified logged in user.
// Include this function in your global custom code header
function getJwtToken() {
return document.cookie.split('; ').reduce((acc, cookie) => {
const [cookieName, cookieValue] = cookie.split('=');
if (cookieName === 'jwtToken') {
return cookieValue.split(',');
}
return acc;
}, [])[0];
}
...
// Add 'Authorization' to every request you make
const response = await fetch(`your-middleware.com`, {
headers: {
'Authorization': `Bearer ${getJwtToken()}`
}
});
// In your middleware
async function auth(req) {
const authHeader = req.headers["authorization"];
if (!authHeader || !authHeader.startsWith("Bearer ")) throw Error('Missing Authorization header')
const jwt = authHeader.split(" ")[1];
const response = await fetch("https://yourdomain.softr.app/v1/api/users/validate-token" {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jwt })
});
const body = await response.text()
if (response.ok && body === "true") {
const email = JSON.parse(Buffer.from(jwt.split('.')[1], 'base64').toString()).sub
return email;
} else {
throw Error('Unable to auth token')
}
}
This only works if all your requests are being made from custom code blocks though.
If you’re using softr blocks, you’re in some trouble. I think they expect you to use workflows to call your ‘middleman’ API now, which in there minds is secure as you can’t simply open dev tools to see what endpoints are being called (but still requires you to leave your endpoints exposed) - no official documentation or guidance on this though.
I have 2 custom blocks of code in softr one for superset embedded dashboard and one for n8n for implementing the RLS/RBAC logic to both of them on softr i am thinking of 2 ways, i need some guidance/advice how can this be implemented–
1. Option - 1: Generate a random value/token/hash when a user logs in and store it in DB. Use the token for Superset and N8N.
2. Option - 2: Generate a random value/token/hash in the backend, store it in DB and update it periodically. Use the token for Superset and N8N.—-if you can help me it be really helpful.