Relatude Help

Tokens and who a request runs as

The sign-in routes answer { token, expires, userId }. Every other request sends the token as Authorization: Bearer <token>.

  • A token runs out after TokenLifetime, 12 hours by default. Renew it with auth/refresh. A token whose user node was deleted is refused.
  • auth/session gives a token to a visitor the site has already signed in, so an interface on the same site needs no second sign-in. Send it as JSON. SessionTokens = false turns it off.
  • The default ICmsApiTokens seals tokens with ASP.NET Core data protection, so they cannot be forged or read. Replace its registration to use tokens of another kind.
  • Tokens outlive a restart only when the data protection keys do. Keep the keys, or every restart signs everyone out:
builder.Services.AddDataProtection()
    .PersistKeysToFileSystem(new DirectoryInfo(Path.Combine(builder.Environment.ContentRootPath, "keys")));

The payload's context says how the user reads:

context Means
culture read and write in this culture, such as nb-NO
cultureFallback read a node with no version in the culture in another culture
edit edit view: unpublished nodes too, with edit-view access checked beside read access
hidden include nodes of hidden types
revisions { nodeId: revisionId }: which revision of a node to read and write (Revisions and cultures)
collection the site the user works in: new nodes go in it (Sites)
links "stored": HTML and Markdown with their links as # tokens, not as URLs

An editor that writes back what it reads should use links: "stored", so its links stay links by id however the URLs change. content-links says what the tokens point at.

Reads run as the user. Every query applies the user's read access, and so do get and exists: they go through a query, because a read by id ignores read access.

Writes are open to every signed-in user. Restrict them with CmsApiOptions.Authorize. It is called before every command with the caller and the command type (an upload as file-upload), and false answers 403:

.AddApi(o => {
    // only administrators and the editors group may use the API
    o.Authorize = (ctx, command) => ctx.IsAdmin || ctx.IsInGroup(EditorsGroupId);
});

Authorize sees only the command type, and a transaction is one command whatever its actions are. A rule against delete must cover transaction too.

AllowAnonymous = true serves requests without a token as the anonymous visitor, for commands that only read.