Guide API documentation Community Applications
Introduction
Authentication
Overview Server application Web Auth SPA, mobile and native Using Postman with Unimicro API
Using the API
Guides
Payroll
Legal

SPA application

For SPA applications we recommend using Implicit flow with silent refresh / sliding-window.

This introduction will use the library oidc-client-ts to demonstrate how you can authenticate your app with the unimicro identity.

Pre-requisits

To follow along this guide you need to have an application set up and these values ready:

  • Client ID
  • Redirect uri
  • Post logout uri

You can create a new application, or find the values over for your already existing applications here.

Creating a new integration
If you dont have a working developer account, you need to reach out to integration team, and they will create on for you. Then you can log in to Applications and continue this guide.

Step 1 - Installing

First step is to get the oidc-client available

Install as package

You can install oidc-client with the termnal

Terminal
npm install oidc-client
Install via CDN

You can install oidc-client via CDN links

index.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/oidc-client/1.11.5/oidc-client.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

Step 2 - Set up UserManager and functions

auth.ts
import { User, UserManager, WebStorageStateStore } from 'oidc-client';

export let authenticatedUser: User | null = null;

// export instance of usermanager
export const userManager = new UserManager({
    authority: 'https://test-login.unimicro.no',
    client_id: '20dabe81-c870-485c-88b1-0074f0a4d296',
    post_logout_redirect_uri: window.location.origin + '/login',
    redirect_uri: window.location.origin + '/callback',
    silent_redirect_uri: window.location.origin + '/callback',
    automaticSilentRenew: true,
    response_type: 'code',
    scope: 'AppFramework Sales.Invoice Sales.Admin Sales.Order Sales.Quote Sales.Manager openid profile',
    userStore: new WebStorageStateStore({ store: window.localStorage }),
});

// initiate auth that gets user if authenticated and stores in local variable
export async function initAuth() {
    const user = await userManager.getUser();
    if (user && !user.expired) {
        authenticatedUser = user;
    }
}

// starts the login with redirect 
export async function login() {
    userManager.signinRedirect();
}

// returns a promise with the user object if logged in, else null
export async function getAuthenticatedUser(): Promise<User | null> {
    const user = await userManager.getUser();
    return user ?? null;
}

You'll notice we set up a few redirects in the oidc configuration. These need to be routes in your SPA framework of choice. In the sections below we'll show you what to do in the callback routes.

Within you SPA framework you might want to take advantage of the frameworks reactivity functionality, like Signals, Observables or Runes. This way you can add subscriptions to changes on the authenticatedUser.

Common pitfalls
If you get errors like "invalid redirect_uri" or "invalid_scope" in the unimicro identity, please validate that redirect_uri and scope in your settings object are exact matches to the values in the developer portal application settings.

Step 3 - Set up callback.html

The callback.html file is the return entry point when the user has authenticated in the identity server.

callback.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/oidc-client/1.11.5/oidc-client.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<script>
    var userManager = new Oidc.UserManager({
        userStore: new Oidc.WebStorageStateStore({
            store: window.localStorage,
        }),
        response_mode: "query",
    });
    userManager.signinRedirectCallback().then(response => {
        window.location = "/app";
    },
    error => {
        console.error(error);
        window.location = "/login";
    });
</script>

Replace the redirect urls with you own.. Its important to note here that user userStore -> store has to be the same value as in the auth.ts usermanager object.

Step 4 - Set up silent-renew.html

silent-renew.html
<script src="./oidc-client.min.js"></script>
<script>
    new Oidc.UserManager().signinSilentCallback().catch((err) => {
        console.log(err);
    });
</script>

Step 5 - Sign in

When you have set up the files and created the redirect path, you can try to sign in.. All you have to do is add a button that calls the login function.

login.html
<script lang="ts">
	import { login } from './auth.ts';
</script>

...

<button onclick="login()">Sign in</button>

Step 6 - Success

After login is called and userManager.signinRedirect() is called, identity handles the rest. When the user returns to your site, the callback.html will redirect the user to where you have defined in the config, and the user token and information is now available through the getAuthenticatedUser function..

If you want to see actual examples of this flow implemented in various frameworks, Uni micro provides starter templates for Vue, SvelteKit, Angular, React, React Native, ASP.NET and Blazor. You can find links to them under applications. And we are adding more frameworks soon.