diff --git a/modules/ROOT/pages/trusted-auth-sdk.adoc b/modules/ROOT/pages/trusted-auth-sdk.adoc index eb3b02805..56275764a 100644 --- a/modules/ROOT/pages/trusted-auth-sdk.adoc +++ b/modules/ROOT/pages/trusted-auth-sdk.adoc @@ -13,10 +13,12 @@ When `init()` is called, the SDK checks if there is an existing ThoughtSpot sess Cookieless authentication, specified using `AuthType.TrustedAuthTokenCookieless`, uses the token as a bearer token for all subsequent requests to ThoughtSpot, without establishing a session in the browser. -Cookie-based authentication, specified using `AuthType.TrustedAuthToken`, uses the token to create a session in the browser immediately, and does not use the token afterward, instead relying on the established session with the ThoughtSpot instance. +Cookie-based authentication, specified using `AuthType.TrustedAuthToken`, uses the token to create a session in the browser immediately. It does not use the token afterward; instead, it relies on the established session with the ThoughtSpot instance. For the request to be *secure*, the user in the browser cannot modify the request or make their own valid request to the *token request service* in a way that requests a token for any other user. +The `autoLogin: true` property in the `init()` function causes the Visual Embed SDK to request a new token before the current token or the session expires, so that a user never sees the embedded ThoughtSpot component in a signed-out state. + == Define token request service There are two options in the `init()` function to define the request to the *token request service*: `authEndpoint` or `getAuthToken`. @@ -25,9 +27,9 @@ The `authEndpoint` parameter of the `init()` function specifies a URL for a dire Any authentication details must be included by the browser in this automated GET request, typically in the cookies. -It is *insecure* to allow specifying the username of the desired login token in the URL called by `authEndpoint`, because any user could request tokens for other users. Instead, the *token request service* itself must be able to determine which user is logged in from the backend. +It is *insecure* to allow specifying the username of the desired login token in the URL called by `authEndpoint`, because any user could request tokens for other users. Instead, the *token request service* must determine the logged-in user from the backend. -Cookies are not sent across domains (only to sub-domains), so your *token request service* must be *hosted in the same domain* as the embedding application. +Cookies are not sent across domains (only to subdomains), so your *token request service* must be *hosted in the same domain* as the embedding application. If you need more control beyond a GET request, use `getAuthToken` instead to define a customized request. @@ -40,8 +42,8 @@ The callback function must return a *Promise* that resolves with the *login toke ---- init({ thoughtSpotHost: "<%=tshost%>", - authType: AuthType.TrustedAuthToken, - username: "UserA", + authType: AuthType.TrustedAuthTokenCookieless, + autoLogin: true, getAuthToken: () => { // fetch() returns a Promise naturally. Assumes a JSON response from the token request service with a 'token' property return fetch('https://my-backend.app/ts-token') @@ -51,14 +53,13 @@ init({ }); ---- -You can even use the callback function to reference a hard-coded login token, in a testing or other appropriate situation. Remember, it must return a Promise that resolves with the token: +You can even use the callback function to reference a hard-coded login token in a testing or other appropriate situation. Remember, it must return a Promise that resolves with the token: [source,JavaScript] ---- init({ thoughtSpotHost: "<%=tshost%>", - authType: AuthType.TrustedAuthToken, - username: "", + authType: AuthType.TrustedAuthTokenCookieless, getAuthToken: () => { let tsToken = '{long-lived-token}'; return Promise.resolve(tsToken); @@ -90,7 +91,7 @@ The Visual Embed SDK provides a link:https://developers.thoughtspot.com/docs/Fun Please see the documentation on xref:rest-apiv2-js.adoc[REST API V2.0 within a browser] for further explanation and example code. === Multiple user sessions in one browser -Cookieless authentication is also useful for scenarios where the embedding application allows for being logged into multiple user accounts in different tabs, or quick switches between users. Cookie-based authentication restricts the whole browser to a single logged-in user per ThoughtSpot instance, while cookie-less allows each tab to use a different token without conflicts. +Cookieless authentication is also useful for scenarios where the embedding application allows for being logged into multiple user accounts in different tabs, or quick switches between users. Cookie-based authentication restricts the whole browser to a single logged-in user per ThoughtSpot instance, while cookieless allows each tab to use a different token without conflicts. == Code examples The only difference between cookie-based trusted authentication and cookieless authentication in the `init()` function is the value used for the `authType` property. @@ -104,38 +105,39 @@ The following example shows a custom callback function with a custom request usi let tsToken; // global scope to store token for other REST API requests init({ thoughtSpotHost: tsURL, - authType: AuthType.TrustedAuthTokenCookieless, - getAuthToken: getAuthToken - }); + authType: AuthType.TrustedAuthTokenCookieless, + getAuthToken: getAuthToken, + autoLogin: true +}); function async getAuthToken { - const tokenURL = tokenServiceURL + "/gettoken/"; - console.log("calling token server at " + tokenURL); - - const timeoutSecs = 5 * 1000; // seconds to milliseconds - - const response = await timeout(timeoutSecs, fetch( - tokenURL, - { - method: 'POST', - mode: 'cors', - cache: 'no-cache', - headers: { - // This Token Request Service returns the token as a plain-text string - 'Content-Type': "text/plain", - // Custom header for passing a JWT with auth details from the web app to the token request service - // Instead the token request service may have access to a user session with the details - 'X-Auth-Token': authJWT - }, - credentials: 'include' - } - )) - - // Token request service returns plain-text string of the token - // set the global tsToken variable for using the token for separate REST API requests - tsToken = response.text(); - // Must return for the Promise to be completed - return response.text() + const tokenURL = tokenServiceURL + "/gettoken/"; + console.log("calling token server at " + tokenURL); + + const timeoutSecs = 5 * 1000; // seconds to milliseconds + + const response = await timeout( + timeoutSecs, + fetch(tokenURL, { + method: 'POST', + mode: 'cors', + cache: 'no-cache', + headers: { + // This Token Request Service returns the token as a plain-text string + 'Content-Type': "text/plain", + // Custom header for passing a JWT with auth details from the web app to the token request service + // Instead the token request service may have access to a user session with the details + 'X-Auth-Token': authJWT + }, + credentials: 'include' + }) + ) + + // Token request service returns plain-text string of the token + // set the global tsToken variable for using the token for separate REST API requests + tsToken = response.text(); + // Must return for the Promise to be completed + return response.text() } ---- @@ -146,8 +148,8 @@ function async getAuthToken { init({ thoughtSpotHost: "", authType: AuthType.TrustedAuthToken, - username: "", authEndpoint: "https://authenticator-server:/endpoint", + autoLogin: true }); ---- @@ -156,12 +158,12 @@ init({ init({ thoughtSpotHost: "", authType: AuthType.TrustedAuthToken, - username: "", + autoLogin: true, getAuthToken: () => { return fetch('https://my-backend.app/ts-token') .then((response) => response.json()) .then((data) => data.token); - }); +}); ---- === Cookieless authentication examples @@ -172,6 +174,7 @@ init({ thoughtSpotHost: "", authType: AuthType.TrustedAuthTokenCookieless, authEndpoint: "https://authenticator-server:/endpoint", + autoLogin: true }); ---- @@ -181,10 +184,11 @@ init({ init({ thoughtSpotHost: "", authType: AuthType.TrustedAuthTokenCookieless, + autoLogin: true, getAuthToken: () => { return fetch('https://my-backend.app/ts-token') .then((response) => response.json()) .then((data) => data.token); } - }); +}); ----