Configuring authentication

One of the first things you should do when embedding Weavy in your application is enabling Single Sign-On (SSO) to provide users with a seamless login experience. This is done by creating and passing a JSON Web Token (JWT) from your backend system to the Weavy client SDK.

JWT is an open standard RFC 7519 for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret with the HMAC algorithm or a public/private key pair using RSA or ECDSA. When tokens are signed using public/private key pairs, the signature also certifies that only the party holding the private key is the one that signed it.

Read more about JSON Web Tokens at jwt.io

Creating the JSON Web Token

When a user has been authenticated in your application, you should create a JWT with user claims and pass it to the Weavy client SDK.

The token you create must include a claim that references an authentication client in Weavy. This is done by setting the iss or client_id claim to the client id of the server configured authentication client you are using. Lastly, the token must be signed with the secret that is defined for the authentication client.

Depending on what technologies your application is based on, there are numerous libraries to help you with the creation of a JWT. Take a look at the Libraries section at jwt.io for some examples.

The token should never by created with client side scripting since that will risk exposing the secret used to sign the token.

For instance, if your application is based on .NET you could use JWT.net to create a token as in the example below:

var token = new JwtBuilder()
    .WithAlgorithm(new HMACSHA256Algorithm())    
    .AddClaim("exp", DateTimeOffset.UtcNow.AddSeconds(60).ToUnixTimeSeconds())    
    .AddClaim("iss", "unique_application_id")
    .AddClaim("sub", "unique_user_id")
    .AddClaim("client_id", "my_client_id")
    .WithSecret("my_client_secret")
    .Encode();

The example above would require that there is an authentication client with client id = my_client_id and client secret = my_client_secret

The token you create must have the following required claims:

Claim Description
exp The expiration time of the token. This should preferably be set to a short time for security reasons.
iss A name or id that uniquely identifies your application. If you don't add the client_id claim this claim needs to be the client id of the authentication client you are using to create the token.
sub A unique identifier for the user in your application, usually the user id.

Additionally you can also include the following optional claims:

Claim Description
client_id The client id of the server configured authentication client that you are using to create the token.
dir Id or name of user directory where the user belongs.
email Email address. If present, this is used to check if a user already exists in Weavy or if a new user account should be created.
name Display name of user (Firstname Lastname).
picture User profile picture. Either an url to an image that is publicly accessible or a base64 encoded data URL (data:image/...)
username Preferred username.

Passing the JWT to Weavy

Tokens can be passed to Weavy either as a string or as a function that returns a javascript promise containing the JWT. An advantage with specifying a function is that it will make it possible to refresh the JWT by calling the function throughout the life cycle of the page.

Tokens can be defined in options when you make a new Weavy({ jwt: jwtProvider } or by calling setJwt(jwtProvider). We recommend defining it in Weavy options.

In order for Weavy to validate your JWT, the client_id (or iss) claim must be identical to the client id of an existing, active Weavy client. Also, the token must be signed with the same secret that the Weavy client is using.

As a JWT provider function

When a new token is needed, Weavy can request a token by itself if you pass a JWT provider function. Your function will be called when a new token is needed, for instance when the token has expired. The function should return a fresh token as a string or return a Promise that resolves the token as a string, for instance return new Promise(...) or return $.ajax(...). Your function could for example perform calls to your backend to retrieve a fresh token, then resolve or reject the promise once the result is processed.

Just pass your function as the jwt option when you create a new Weavy() in your code.

Function returning a String

<script>
    var getToken = function () {
        return "server_generated_token";
    }

    var weavy = new Weavy({
        jwt: getToken
    });
</script>

Function returning a Promise

<script>
    var getToken = function () {
        return new Promise(function (resolve, reject) {
            // could for instance call backend to generate a valid token
            var token = getTokenFromSomewhere();
            if (token) {
                resolve(token);
            } else {
                reject("Failed to retrieve token");
            }
        });
    }

    var weavy = new Weavy({
        jwt: getToken
    });
</script>

Function returning an Ajax Promise

<script>
    var getToken = function () {
        // Using jQuery ajax for example
        return $.ajax({
            url: "/myapi/getmytoken",
            xhrFields: {
                // Make sure to enable cookies if needed
                withCredentials: true
            }
        });
    }

    var weavy = new Weavy({
        jwt: getToken
    });
</script>

As a string

You can pass the JWT directly to Weavy by specifying the jwt option in the client. This way weavy can't request a new token when needed the same way as a JWT provider function can.

<script>
    var weavy = new Weavy({
        jwt: "server_generated_token"
    });
</script>

Changing a user

Signing in another user will automatically sign out the previous user. If you have defined a jwt provider function that automatically gets the new token for the new user, you would only need to call signIn() to fetch the token and sign-in in Weavy.

If you need to define a new string JWT or a new jwt provider function you can do so by using setJwt(jwt). After the new token is defined you may call signIn() at any time to sign-in in Weavy.

You may also pass a new string JWT or JWT provider function directly into the signIn(jwt) to both set the JWT and sign-in right away.

The sign-in function returns a Promise, so you can wait for the process to complete before doing other things.

Passing a new JWT string or JWT provider function into setJwt(jwt) or signIn(jwt) will always replace the existing JWT provider.

Changing a user with a JWT provider function

<script>
    var weavy = new Weavy({
        jwt: function () {
            return getJwtSomewhere();
        }
    });

    // Change the user at a later point.
    // This will fetch a fresh token from the JWT provider function.
    weavy.authentication.signIn();
</script>

Changing a user with a JWT string

<script>
    var weavy = new Weavy({
        jwt: "first_server_generated_token"
    });

    // Change the user at a later point.
    // This replaces the previously defined JWT.
    weavy.authentication.setJwt("second_server_generated_token");
    weavy.authentication.signIn();
</script>

Signing out a user

You may explicitly sign out the current user by calling the signOut() function.

You may also clear the JWT provider on sign-out by using signOut(true), which is not recommended if you use a properly configured JWT provider function.

The sign-out function returns a Promise, so you can wait for the process to complete before doing other things.

If you also clear the JWT provider on signOut, you must define a new JWT provider before signing in again.
<script>
    var weavy = new Weavy();
    weavy.authentication.signOut().then(function () {
        console.log("The user was signed out from Weavy");
    });
</script>