Authentication
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) => "wyu_**********";
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 ahttp://localhost:5080/docs/reference/uikit-web/components/chatnd 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 data = await response.json();
// return access_token to UIKit
return data.access_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;