Frontend Authentication Header Specification (WebUI Internal Open)
When the frontend sends backend requests, it must read the current website cookies.
Cookies that must be read:
TMSESSNAME
X-Csrf-Token
Request headers must include:
X-Csrf-Token: <X-Csrf-Token value read from cookie>
Cookie: TMSESSNAME=<TMSESSNAME value read from cookie>; X-Csrf-Token=<X-Csrf-Token value read from cookie>;
Example:
X-Csrf-Token: ltRoTGSICC68drxbvljhBeD2DZ7LPcge
Cookie: TMSESSNAME=46958db9-1f8a-4686-b340-34fd8ccf62e8; X-Csrf-Token=ltRoTGSICC68drxbvljhBeD2DZ7LPcge;
Frontend Implementation Example:
function getCookie(name) {
const prefix = encodeURIComponent(name) + "=";
return document.cookie
.split(";")
.map((item) => item.trim())
.find((item) => item.startsWith(prefix))
?.slice(prefix.length) || "";
}
const sessionName = getCookie("TMSESSNAME");
const csrfToken = getCookie("X-Csrf-Token");
const headers = {
"Content-Type": "application/json",
"X-Csrf-Token": csrfToken,
"Cookie": `TMSESSNAME=${sessionName}; X-Csrf-Token=${csrfToken};`
};
Note
- Browsers do not allow the frontend to manually set the standard
Cookieheader. - This specification uses the custom header
Cookieto pass the concatenated cookie string. Cookieis a fixed key name and must be spelled as required by the platform.- Requests should retain
credentials: "include".
If the backend needs to support browser preflight requests, it should allow the following headers:
Content-Type
X-Csrf-Token
Cookie
Cookie Header Naming Note: The custom header name Cookie is a platform internal naming convention. It bypasses the browser's restriction on setting the standard Set-Cookie header in JavaScript fetch/XHR requests. This name is fixed and must not be changed — any deviation will break authentication.
Backend Authentication Validation Example (Python):
def validate_auth(headers):
'''Validate the Cookie authentication header from frontend requests.'''
cookie_str = headers.get('Cookie', '')
csrf_token = headers.get('X-Csrf-Token', '')
# Parse Cookie header (format: key1=val1; key2=val2)
parts = {}
for part in cookie_str.split(';'):
if '=' in part:
k, v = part.strip().split('=', 1)
parts[k.strip()] = v.strip()
session_name = parts.get('TMSESSNAME', '')
cookie_csrf = parts.get('X-Csrf-Token', '')
if not session_name or not csrf_token:
return False
if csrf_token != cookie_csrf:
return False
# Validate session via TOS platform
return True
Backend Authentication Validation Example (Go):
func validateAuth(r *http.Request) bool {
cookieStr := r.Header.Get("Cookie")
csrfToken := r.Header.Get("X-Csrf-Token")
if cookieStr == "" || csrfToken == "" {
return false
}
for _, part := range strings.Split(cookieStr, ";") {
kv := strings.SplitN(strings.TrimSpace(part), "=", 2)
if len(kv) == 2 && kv[0] == "X-Csrf-Token" {
if kv[1] != csrfToken {
return false
}
}
}
return true
}
Token Expiry and Session Invalidation Handling:
- When the authentication token expires or the session becomes invalid, the backend must return HTTP
401 Unauthorized - The frontend must detect the 401 response and redirect to the TOS login page
- Do not attempt to auto-refresh the token; redirect to
/to trigger TOS re-authentication
fetch('/v2/proxy/myapp/api', { credentials: 'include' })
.then(res => {
if (res.status === 401) {
window.location.href = '/'; // Redirect to TOS login
}
return res.json();
});