Table of Contents

Identity

The frontend identity is based on information it gets from a cookie called .cratis-identity. The purpose of this is to be able to provide identity information to the client at the first render. This allows for a better developer and user experience, as there is no need to call the backend for details about the user.

While in development mode on your local machine, if this cookie does not exist it will call the .cratis/me endpoint from the frontend itself. This makes it possible to work without having to simulate the entire production environment locally.

Important note: Since local development is not configured with the identity provider, but you still need a way to test that both the backend and the frontend deals with the identity in the correct way. This can be achieved by creating the correct token and injecting it as request headers using a browser extension. Read more here.

This information found in the cookie is a base64 encoded string containing the JSON structure that is expected.

Identity provider

Identity is a read only feature in the frontend. It can't be manipulated, as it is owned by the backend or the ingress. All access to identity goes through what is called IdentityProvider.

The IdentityProvider provides functionality for getting the current identity.

import { IdentityProvider } from '@cratis/applications/identity';

const identity = await IdentityProvider.getCurrent();

console.log(`Hello '${identity.name}'`);

Note that the getCurrent() method is an asynchronous operation that returns a promise. The reason for this is that if the cookie is not found, it will call the .cratis/me endpoint to try to get the identity.

Details

Part of the identity can hold details that are beyond what the identity provider provides. These details are application specific and something that your application or ingress should be responsible for filling out. Details can be considered optional, as that might not be a requirement for your application.

The getCurrent() method takes a generic parameter that allows you to specify the type of the details object.

import { IdentityProvider } from '@cratis/applications/identity';

type IdentityDetails = {
    department: string,
    age: number
};

const identity = await IdentityProvider.getCurrent<IdentityDetails>();

console.log(`Hello '${identity.name}' from ´${identity.details.department}`);

IIdentity

The return type coming from getCurrent() looks like the following:

Name Type Description
id string The unique identifier from the identity provider
name string The user name
claims { [key: string]: string; } Key/value of strings holding claims
details any / type Any additional identity details with type given, defaults to any

Refresh

In some scenarios you might need to refresh the identity. Typically if the user has been granted more access or details has been updated. Rather than having your user log out and back in again, you can issue a refresh. Since the cookie is there and not governed by the frontend, it needs to call the backend or ingress to perform the refresh. The refresh calls the .cratis/me endpoint which returns the identity and details. This endpoint should also be responsible for updating the cookie so that any call to getCurrent() on the IdentityProvider gives you the correct identity and details.

To refresh the identity you can call the refresh() method on the identity object itself.

import { IdentityProvider } from '@cratis/applications/identity';

let identity = await IdentityProvider.getCurrent();
identity = await identity.refresh();

The identity object is designed to be immutable, leading to the refresh() method having to return a new instance. This means that the original identity instance won't be updated and you would have to replace it if you have it as a variable.