Bearer token
Authenticating with a configured access token — for a service, a script or a plugin — and why previews need a cookie anyway.
An access token configured on the server authorises a fixed set of API methods. Send it and every request is authenticated: no form, no redirect, no session to establish. This is the mode for a service, a scheduled job, a script, or a plugin.
import { AuthMode } from "@sinequa/atomic";
client.configure({ authMode: AuthMode.bearer(token) });
await client.auth.login();The token is sent as Authorization: Bearer on every request.
Browser or not: one decision
Why a token-based sign-in still wants a cookie
The cookie is not for this library — which authenticates itself on every request. It is for the browser. An
<iframe> showing a document preview, the stylesheet and images that preview references, an <img> thumbnail,
a download link: none of them can carry an Authorization header. Measured against a live backend, they answer
200 with the cookie and 559 without — so a preview is blank however well your application is authenticated.
What login() does in this mode
Unlike every other mode, it does not look for an existing session first — the token is the credential:
- Unless
sessionCookie: false, it postssecurity.webtokento trade the token for a session cookie. - If the server refuses that exchange, the sign-in continues — this is not fatal.
- It then validates the token against a protected endpoint and records the authenticated state explicitly. On
this path there is no client token, so
isAuthenticated()relies on a stored flag, exactly as token-less ambient SSO does.
A missing or refused token throws, with the reason. There is no fallback screen: a password form for an authentication that has no password is a dead end.
Two deployments
import { AuthMode, createAtomicClient } from "@sinequa/atomic";
/**
* Headless: no browser, so the cookie exchange buys nothing. Skipping it removes a
* round trip and an error log on every start-up.
*/
const client = createAtomicClient({
app: "<your-app>",
backendUrl: "https://<your-sinequa-server>",
authMode: AuthMode.bearer(process.env.SINEQUA_TOKEN ?? "", { sessionCookie: false }),
});
await client.initializeConfig();
// Throws if the token is missing or refused — there is nothing to fall back to.
await client.auth.login();
const result = await client.api.query.search({
name: "<your-query>",
text: "quarterly report",
pageSize: 100,
});
console.log(`${result.rowCount} documents`);import { InjectionToken, inject, provideAppInitializer } from "@angular/core";
import { AuthMode, type AtomicClient, createAtomicClient } from "@sinequa/atomic";
import { environment } from "../environments/environment";
/**
* A browser application authenticated by a token: keep the default
* sessionCookie: true, or document previews shown in an iframe come back blank.
*/
export const SINEQUA = new InjectionToken<AtomicClient>("Sinequa client", {
factory: () =>
createAtomicClient({
app: environment.sinequaApp,
backendUrl: environment.sinequaUrl,
authMode: AuthMode.bearer(environment.sinequaToken),
}),
});
export function provideSinequa() {
return provideAppInitializer(async () => {
const client = inject(SINEQUA);
await client.initializeConfig();
// Throws on a missing or refused token: let it fail loudly rather than render
// an application that cannot make a single call.
await client.auth.login();
});
}import { AuthMode, createAtomicClient } from "@sinequa/atomic";
/**
* A browser application authenticated by a token: keep the default
* sessionCookie: true, or document previews shown in an iframe come back blank.
*/
export const sinequa = createAtomicClient({
app: import.meta.env.VITE_SINEQUA_APP,
backendUrl: import.meta.env.VITE_SINEQUA_URL,
// The env value is `string | undefined`; bearer() requires a string, and an
// empty one fails loudly at login() rather than silently sending no header.
authMode: AuthMode.bearer(import.meta.env.VITE_SINEQUA_TOKEN ?? ""),
});
export const ready = (async () => {
await sinequa.initializeConfig();
// Throws on a missing or refused token — surface it rather than rendering an
// application that cannot make a single call.
await sinequa.auth.login();
})();A token in front-end code is readable by anyone
Anything shipped to a browser — an environment variable inlined at build time included — is public. Use this mode in a browser only for a token whose rights you are willing to hand to every visitor. Otherwise keep the token server-side and put your own backend in front.
Getting previews to work
If document previews are blank while everything else succeeds, the cookie exchange was refused. The error looks like this, and it is explicit:
The JSON method 'webtoken' is not allowed by the access token '…' as none of the JSON
method rules allow it.An access token whitelists the JSON methods it may call, and webtoken — the login method an access token
replaces — is often not among them. The fix is on the access token's own rules, not the web
application's global list, which is what that message names.
The refusal is logged at debug and the fallback at info, so a supported configuration does not report an
error on every boot.