Authentication configuration in UIKit Web

For single-sign-on (SSO) and seamless authentication between your app and Weavy, you want the UIKit to act on behalf of your authenticated user. This is known as user-to-server communication and for this to work you need to configure the UIKit with a tokenFactory that it can call whenever it needs to make an API request to the Weavy environment.

Token URL

The simplest way to configure a tokenFactory is to set the tokenUrl property. The UIKit comes with a predefined tokenFactory that can be activated by defining the tokenUrl. The url should point to an endpoint on your backend that provides a JSON response with an access_token. Whenever a fresh new token is needed, the url is called with a ?refresh=true query parameter.

weavy.tokenUrl = new URL("https://myserver.example.com/api/token");

To use the tokenUrl and the predefined tokenFactory, the endpoint needs to return access_token as JSON data.

{
  "access_token": "wyu_**********"
}

Read about providing an access token endpoint for authentication.

Token factory

Using a custom tokenFactory provides you with the possibility to customize and retrieve the access_token any way that fits your needs. The tokenFactory should just be an async function that returns an access_token for the authenticated user in some way.

weavy.tokenFactory = async (refresh) => "access_token";

The tokenFactory is typically implemented as an API call to your application backend which performs a server-to-server request to the Weavy user token endpoint and then returns the access_token to the UIKit.

To improve response times and reduce unnecessary roundtrips, it is a good practice for your application to store and reuse tokens instead of always requesting new tokens from the Weavy environment. When the UIKit detects an expired or revoked token, your tokenFactory will be called with refresh=true. This allows your code to clear the invalid token from your application’s storage and request a new token from the Weavy environment.

Example implementation

The following example code shows what a typical implementation of the tokenFactory and corresponding server-side code in your application could look like. As seen in the example, we recommend your server stores and reuses tokens as this avoids unnecessary roundtrips.

Example: A tokenFactory that makes a fetch request to a token endpoint on your application backend.

const weavy = new Weavy();

weavy.url = new URL("https://myenvironment.weavy.io");

// configure Weavy with tokenFactory
weavy.tokenFactory = async (refresh) => {

  // fetch access_token from server
  const response = await fetch("/api/token?refresh=" + refresh);

  if (response.ok) {
    const token = await response.text().access_token;

    // return access_token to UIKit
    return token;
  } else {
    throw new Error("Could not fetch token from endpoint");
  }
};

Example: ASP.NET implementation of the server-side code called from the tokenFactory.

[HttpGet("~/api/token")]
public async Task<IActionResult> GetToken(bool refresh = false) {
    // get uid for the authenticated user
    var uid = User.Identity.Name;

    // check local token store for existing access_token
    if (!refresh && _tokens.TryGetValue(uid, out var existingToken)) {
        // return existing token
        return Content(existingToken);
    }

    // get weavy url and api key from config
    var weavyUrl = _config["WEAVY-SERVER"];
    var apiKey = _config["WEAVY-API-KEY"];

    // request access_token from Weavy
    _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
    var response = await _httpClient.PostAsync($"{weavyUrl}/api/users/{uid}/tokens", null);
    if (response.IsSuccessStatusCode) {
        // read access_token
        var resp = await response.Content.ReadFromJsonAsync<TokenResponse>();
        var accessToken = resp.AccessToken;

        // store and return access_token
        _tokens[uid] = accessToken;
        return Content(accessToken);
    }

    return BadRequest();
}

Clearing a user

When your users signs out you can destroy the Weavy instance to disconnect the user and prevent further usage.

const weavy = new Weavy();
...
weavy.destroy();
weavy = undefined;