[[_nodejs_adapter]] === Node.js Adapter {project_name} provides a Node.js adapter built on top of https://github.com/senchalabs/connect[Connect] to protect server-side JavaScript apps - the goal was to be flexible enough to integrate with frameworks like https://expressjs.com/[Express.js]. ifeval::[{project_community}==true] The library can be downloaded directly from https://www.npmjs.com/package/keycloak-connect[ {project_name} organization] and the source is available at https://github.com/keycloak/keycloak-nodejs-connect[GitHub]. endif::[] To use the Node.js adapter, first you must create a client for your application in the {project_name} Administration Console. The adapter supports public, confidential, and bearer-only access type. Which one to choose depends on the use-case scenario. Once the client is created click the `Installation` tab, select `{project_name} OIDC JSON` for `Format Option`, and then click `Download`. The downloaded `keycloak.json` file should be at the root folder of your project. ==== Installation Assuming you've already installed https://nodejs.org[Node.js], create a folder for your application: mkdir myapp && cd myapp Use `npm init` command to create a `package.json` for your application. Now add the {project_name} connect adapter in the dependencies list: ifeval::[{project_community}==true] [source,json,subs="attributes"] ---- "dependencies": { "keycloak-connect": "{project_versionNpm}" } ---- endif::[] ifeval::[{project_product}==true] [source,json,subs="attributes"] ---- "dependencies": { "keycloak-connect": "file:keycloak-connect-{project_versionNpm}.tgz" } ---- endif::[] ==== Usage Instantiate a Keycloak class:: The `Keycloak` class provides a central point for configuration and integration with your application. The simplest creation involves no arguments. [source,javascript] ---- var session = require('express-session'); var Keycloak = require('keycloak-connect'); var memoryStore = new session.MemoryStore(); var keycloak = new Keycloak({ store: memoryStore }); ---- By default, this will locate a file named `keycloak.json` alongside the main executable of your application to initialize keycloak-specific settings (public key, realm name, various URLs). The `keycloak.json` file is obtained from the {project_name} Admin Console. Instantiation with this method results in all of the reasonable defaults being used. As alternative, it's also possible to provide a configuration object, rather than the `keycloak.json` file: [source,javascript] ---- let kcConfig = { clientId: 'myclient', bearerOnly: true, serverUrl: 'http://localhost:8080/auth', realm: 'myrealm', realmPublicKey: 'MIIBIjANB...' }; let keycloak = new Keycloak({ store: memoryStore }, kcConfig); ---- Applications can also redirect users to their preferred identity provider by using: [source,javascript] ---- let keycloak = new Keycloak({ store: memoryStore, idpHint: myIdP }, kcConfig); ---- Configuring a web session store:: If you want to use web sessions to manage server-side state for authentication, you need to initialize the `Keycloak(...)` with at least a `store` parameter, passing in the actual session store that `express-session` is using. [source,javascript] ---- var session = require('express-session'); var memoryStore = new session.MemoryStore(); var keycloak = new Keycloak({ store: memoryStore }); ---- Passing a custom scope value:: By default, the scope value `openid` is passed as a query parameter to {project_name}'s login URL, but you can add an additional custom value: [source,javascript] var keycloak = new Keycloak({ scope: 'offline_access' }); ==== Installing Middleware Once instantiated, install the middleware into your connect-capable app: [source,javascript] ---- var app = express(); app.use( keycloak.middleware() ); ---- ==== Checking Authentication To check that a user is authenticated before accessing a resource, simply use `keycloak.checkSso()`. It will only authenticate if the user is already logged-in. If the user is not logged-in, the browser will be redirected back to the originally-requested URL and remain unauthenticated: [source,javascript] ---- app.get( '/check-sso', keycloak.checkSso(), checkSsoHandler ); ---- ==== Protecting Resources Simple authentication:: To enforce that a user must be authenticated before accessing a resource, simply use a no-argument version of `keycloak.protect()`: [source,javascript] ---- app.get( '/complain', keycloak.protect(), complaintHandler ); ---- Role-based authorization:: To secure a resource with an application role for the current app: [source,javascript] ---- app.get( '/special', keycloak.protect('special'), specialHandler ); ---- To secure a resource with an application role for a *different* app: [source,javascript] app.get( '/extra-special', keycloak.protect('other-app:special'), extraSpecialHandler ); To secure a resource with a realm role: [source,javascript] app.get( '/admin', keycloak.protect( 'realm:admin' ), adminHandler ); Advanced authorization:: To secure resources based on parts of the URL itself, assuming a role exists for each section: [source,javascript] ---- function protectBySection(token, request) { return token.hasRole( request.params.section ); } app.get( '/:section/:page', keycloak.protect( protectBySection ), sectionHandler ); ---- ==== Additional URLs Explicit user-triggered logout:: By default, the middleware catches calls to `/logout` to send the user through a {project_name}-centric logout workflow. This can be changed by specifying a `logout` configuration parameter to the `middleware()` call: [source,javascript] app.use( keycloak.middleware( { logout: '/logoff' } )); {project_name} Admin Callbacks:: Also, the middleware supports callbacks from the {project_name} console to log out a single session or all sessions. By default, these type of admin callbacks occur relative to the root URL of `/` but can be changed by providing an `admin` parameter to the `middleware()` call: [source,javascript] app.use( keycloak.middleware( { admin: '/callbacks' } );