OpenId Connect Authentication with Node.js (openid-client)

To log in a user according to this guide, you must have configured an application (client) as a web application (server).

To log in a user, you can use the OpenID Connect support available in openid-client.

import express from "express";
import { Issuer, generators } from "openid-client";

const app = express();

// -----------------------------
// Discover OIDC Provider
// -----------------------------
(async () => {
  const issuer = await Issuer.discover(
    "https://environment-company.irmciam.se/.well-known/openid-configuration"
  );

  client = new issuer.Client({
    client_id: "client-id-from-portal",
    client_secret: "client-secret-from-portal",
    token_endpoint_auth_method: "client_secret_basic",
  });

  console.log("OIDC client initialized");
})();



// -----------------------------
// Login Endpoint
// -----------------------------
app.get("/", async (req, res) => {
  const code_verifier = generators.codeVerifier();
  const code_challenge = generators.codeChallenge(code_verifier);
  const state = generators.state();

  req.session.code_verifier = code_verifier;
  req.session.state = state;

  const authUrl = client.authorizationUrl({
    scope: "openid profile email org",
    response_type: "code",
    redirect_uri: "http://localhost:3000/callback",
    state,
    code_challenge,
    code_challenge_method: "S256",
  });

  res.redirect(authUrl);
});

// -----------------------------
// Callback Endpoint
// -----------------------------
app.get("/callback", async (req, res) => {
  try {
    const params = client.callbackParams(req);

    const tokenSet = await client.callback(
      "http://localhost:3000/callback",
      params,
      {
        state: req.session.state,
        code_verifier: req.session.code_verifier,
      }
    );

    const claims = tokenSet.claims();

    res.json({
      access_token: tokenSet.access_token,
      id_token: tokenSet.id_token,
      user: claims,
    });

  } catch (err) {
    console.error(err);
    res.status(500).send("Authentication failed");
  }
});