npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@fingerprintsoft/ionic-keycloak-auth

v0.0.4

Published

Authentication bei Keycloak for Ionic 4+

Downloads

3

Readme

Ionic Keycloak Auth

npm version FOSSA Status

This module is designed for Ionic 4 with angular 7+ on Android and IOS platforms only, and with keycloak 6+

To know

This library provides

  • an HttpInterceptor which automatically attaches a JSON Web Token to HttpClient requests.
  • an Authentication Service which permit authentication through browser-tab (or in-app-browser when the first isn't usable).

This library does rely on the Jwt Library of Auth0 for handling tokens.

Installation

# installation with npm 
npm i @fingerprintsoft/ionic-keycloak-auth
  
# installation with yarn 
yarn add @fingerprintsoft/ionic-keycloak-auth

Usage

Using this plugin requires two se-up parts, first using ionic plugins and then a small part about cordova, as stated in the official documentation.

Ionic Setup

These plugins are required to be setup when using this plugin:

# The scheme "myapp" here would be used to open back the app, so don't forget it. 
# Some may also use the host "myapp.com" to do it, depending on the configuration
# of the Keycloak
ionic cordova plugin add ionic-plugin-deeplinks --variable URL_SCHEME=myapp --variable DEEPLINK_SCHEME=https --variable DEEPLINK_HOST=myapp.com --variable ANDROID_PATH_PREFIX=/
npm install @ionic-native/deeplinks

# Install the browsertab
ionic cordova plugin add cordova-plugin-browsertab
npm install @ionic-native/browser-tab

# Install the inAppBrowser
ionic cordova plugin add cordova-plugin-inappbrowser
npm install @ionic-native/in-app-browser

# Install the keycloak adapter
npm install keycloak-js@your-version

And then import it in the AppModule:

import {NgModule} from '@angular/core';
import {environment} from '../environments/environment';
import {IonicKeycloakAuthModule} from '@fingerprintsoft/ionic-keycloak-auth';
...

@NgModule({
    imports: [
    ...
    IonicKeycloakAuthModule.forRoot({
        jwtModuleOptions: {
            // Not optional:
            // As absolute necessity, 
            // there should be getters and 
            // setters for the token.
            // These can be async.
            getToken: () => JSON.parse(localStorage.getItem('token')),
            setToken: (value) => localStorage.setItem('token', value ? JSON.stringify(value) : null),
            
            // These configuration are the same 
            // as of Jwt Library.
            // It is to whitelist any domains that you 
            // want to make requests to.
            whitelistedDomains: ["example.com"],
            
            // Here the inverse for blacklisted Routes
            blacklistedRoutes: ["example.com/examplebadroute/"]
        },
        deepLinksConfig: {
            // Not optional: 
            // Here is the reference of the scheme, 
            // which was used for the deeplinks before.
            deepLinkingScheme: 'myapp'
        },
        keycloakConfig: {
            // Not optional:
            // You need to define where the configuration 
            // for the keycloak is to be found. This 
            // can also be async.
            jsonConfig: () => environment.keycloakConfig
        }
    })
    ],
    ...
})
export class AppModule {
}

Yet you could set up cordova.

Cordova Setup

This is quit simple here. You just need to add some lines to your config.xml, as the documentationo says.

  1. First, add

    <widget>
        <preference name="AndroidLaunchMode" value="singleTask" />
    </widget>

    to make the app open only one single instance oof every browsertab openend, so that it wouldn't create one foor each login.

  2. And then add this so it recognize the keycloak url keycloak-address.com directly when it's on https on IOS.

    <universal-links>
       <host name="keycloak-address.com" scheme="https">
           <path url="/auth" />
       </host>
    </universal-links>

    This will be all for cordova. Again, you should read the official documentation about integrating cordova with keycloak too to understand all choices better

Usage

Now just use the login-Method of the KeycloakAuthService to initiate a login process with keycloak, which will resolve with a AuthToken composed with Token-Response as Keycloak does reply.

import {Component} from '@angular/core';
import {Router} from '@angular/router';
import {KeycloakAuthService} from '@fingerprintsoft/ionic-keycloak-auth';
...

@Component({
  selector: 'page-login',
  templateUrl: 'login.html',
  styleUrls: ['./login.scss'],
})
export class LoginPage {

    constructor(
        public router: Router,
        public keycloakAuthService: KeycloakAuthService,
    ) {
    }
    
    ...
    async keycloakLogin(isLogin: boolean) {
    await this.keycloakAuthService.login(isLogin);
    const sub = this.keycloakAuthService.user()
        .subscribe(async user => {
            if (user) {
                // There is a user in the app
                await this.router.navigateByUrl('/app/tabs/schedule');
            } else {
                // There's no user in the app
            }
            sub.unsubscribe();
        });
    }
    ...

}

When isLogin is true, the login process leads to the login page of Keycloak, while false leads to the registration page. Yet in your template:

<ion-button (click)="keycloakLogin(true)" 
            color="primary" expand="block" 
            shape="round" size="large">
    Login here
</ion-button>

<ion-button (click)="keycloakLogin(false)" 
            fill="clear"
            color="primary" expand="block" 
            shape="round" size="large">
    Sign up
</ion-button>

Configuration Options

There are at time tree groups of options which are:

  • keycloak config,
  • deepLinks config, and
  • jwt config

Keycloak Config

This is at time constituted from a single field, jsonConfig which ist from type FetchKeycloakJSON, which is basically () => KeycloakJsonStructure | Promise<KeycloakJsonStructure>.

The KeycloakJsonStructure here is just the json structure from the keycloak.json which is being exported from keycloak.

You can then configure it in two ways, a direct one, or using a provider:

  1. Using the direct way, by just doing as in the example up there:

    @NgModule({
        imports: [
            ...
            IonicKeycloakAuthModule.forRoot({
                keycloakConfig: {
                    // Not optional:
                    // You need to define where the configuration 
                    // for the keycloak is to be found. This 
                    // can also be async.
                    jsonConfig: () => environment.keycloakConfig
                }
            })
        ],
        ...
    })
    export class AppModule {
    }
  2. Using a provider, as simple as using the KEYCLOAK_OPTIONS token in the kcOptionsProvider:

    import { KEYCLOAK_OPTIONS, IonicKeycloakAuthModule } from '@fingerprintsoft/ionic-keycloak-auth';
    import { KeycloakService } from './keycloak.service';
       
    export function jwtOptionsFactory(kcService: KeycloakService) {
        return {
            tokenGetter: async () => {
                const config = await kcService.getAsyncKeycloakConfig();
                return config;
            }
        }
    }
       
    @NgModule({
        imports: [
            ...
            IonicKeycloakAuthModule.forRoot({
                kcOptionsProvider: {
                    provide: KEYCLOAK_OPTIONS,
                    useFactory: kcOptionsFactory,
                    deps: [KeycloakService]
                }
            })
        ],
        ...
    })
    export class AppModule {
    }

PS:

  • You can't use the two of them at the same time, because one will override the other
  • At time, the function will be called only one time, to make the app faster, as making the fetch request any time may impact performances. For future version, it will be cached

DeepLink Config

This library subscribe to deeplinks at a certain point and need your app scheme to open the app once the browser process is finished.

So this configuration cannot be changed at runtime, so just do as the example provided before:

@NgModule({
   imports: [
       ...
       IonicKeycloakAuthModule.forRoot({
           deepLinksConfig: {
               deepLinkingScheme: 'myapp'
           },
       })
   ],
   ...
})
export class AppModule {
}

Not here, that the field deepLinkingScheme isn't optional then.

Jwt Config

This options can also be made using an injector as the keycloak does, or doing it straight.

  1. Using the straight way is as giving directly the config in the jwtModuleOptions:

    @NgModule({
        imports: [
            ...
            IonicKeycloakAuthModule.forRoot({
                jwtModuleOptions: {
                    // Not optional:
                    // As absolute necessity, 
                    // there should be getters and 
                    // setters for the token.
                    // These can be async.
                    getToken: () => JSON.parse(localStorage.getItem('token')),
                    setToken: (value) => localStorage.setItem('token', value ? JSON.stringify(value) : null),
                       
                    // These configuration are the same 
                    // as of Jwt Library.
                    // It is to whitelist any domains that you 
                    // want to make requests to.
                    whitelistedDomains: ["example.com"],
                       
                    // Here the inverse for blacklisted Routes
                    blacklistedRoutes: ["example.com/examplebadroute/"]
                },
            })
        ],
        ...
    })
    export class AppModule {
    }

    or you could just

  2. Use the JWT_GET_AND_SETTER-injector and inject it as a provider in the jwtConfigProvider-field:

    import { JWT_GET_AND_SETTER, IonicKeycloakAuthModule, AuthToken } from '@fingerprintsoft/ionic-keycloak-auth';
    import { StorageService, JwtService } from './api.service';
       
    export function jwtConfigFactory(storage: StorageService, jwt: JwtService) {
        const config: JwtConfig | any = jwt.getConfig();
        return {
            ...config,
            getToken: async () => {
                const token: AuthToken = await storage.getAsyncToken();
                return token;
            },
            setToken: async (value: AuthToken) => {
                await storage.setAsyncToken(value);
            }
        }
    }
       
    @NgModule({
        imports: [
            ...
            IonicKeycloakAuthModule.forRoot({
                jwtConfigProvider: {
                    provide: JWT_GET_AND_SETTER,
                    useFactory: jwtConfigFactory,
                    deps: [StorageService, JwtService]
                }
            })
        ],
        ...
    })
    export class AppModule {
    }

    And that's all folks!

PS:

  • As the keycloak config resolvers, these can't be use at the same time
  • For more information about each setting here, please just refer to the Jwt's module page, as they're used as they are. Just the tokenGetter-function is missing here.

Keycloak side Configuration

Here, not too much to say. Just that your client shouldn't be bearer-only.

Author

This library is created and maintained by Coding Motion