How to create OIDC Client in Nodejs

Nitesh Singh
4 min readJul 25, 2021

--

Introduction

In this artice we will see how to implement OpenID Client in Nodejs using Passport and openid-client.

If you want to implement your own OAuth2.0 Authorization server, you can follow my this article.

Step-By-Step Implementation

Note : I will use oidc-provider which I had created in previous article and it is running on http://localhost:3000/oidc

You can use any oidc-provider.

  1. we will use npm to create our oidc-client project, First, let’s create our project directory, then we run the init command.
mkdir OIDC-Client
cd OIDC-Client
npm init -y

2. Install required packages

npm install express nodemon cookie-parser express-sessionoryarn add express nodemon cookie-parser express-session

3. create an index.js file and write following codes to create simple server

const express       = require('express');
const session = require('express-session');
const cookieParser = require('cookie-parser');
const path = require("path");
const http = require("http");
const app = express();
app.use(cookieParser());
app.use(express.urlencoded({
extended: true,
}));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
app.use(session({
secret: 'secret',
resave: false,
saveUninitialized: true,}));
const httpServer = http.createServer(app)
httpServer.listen(8080,() =>{
console.log(`Http Server Running on port 3004`)
})

4. Now , Install passport ,openid-client and helmet

I am sure you must be familiar with passport and helmet. if not let’s see in brief.

passport

— Passport is authentication middleware for Node.js. It’s sole purpose is to authenticate requests, which it does through an extensible set of plugins known as strategies.

for this project I am going to use openid-client strategies.

openid-client

— openid-client is a server side OpenID Relying Party (RP, Client) implementation for Node.js runtime.

helmet

— Helmet helps us to secure our Express apps by setting various HTTP headers.

npm install passport openid-client helmetor yarn add passport openid-client helmet

5. Import passport and helmet . To use passport in Express-based application , we will have to configure following middlewares.

const passport = require('passport');
const helmet = require('helmet');
//Helmet midddleware
app.use(helmet());
//Passport Middlewares
app.use(passport.initialize());
app.use(passport.session());

6. Passport maintains persistent login sessions. In order for persistent sessions to work, the authenticated user must be serialized to the session, and deserialized when subsequent requests are made.

passport.serializeUser((user, done) => {
console.log('-----------------------------');
console.log('serialize user');
console.log(user);
console.log('-----------------------------');
done(null, user);
});
passport.deserializeUser((user, done) => {
console.log('-----------------------------');
console.log('deserialize user');
console.log(user);
console.log('-----------------------------');
done(null, user);
});

7. import Issuer and Strategy from openid-client and discover an Issuer configuration using its published .well-known endpoints

const { Issuer,Strategy } = require('openid-client');Issuer.discover('http://localhost:3000/oidc') 
.then(function (oidcIssuer) {
var client = new oidcIssuer.Client({
client_id: 'oidcCLIENT',
client_secret: 'client_super_secret',
redirect_uris: ["http://localhost:8080/login/callback"],
response_types: ['code'],
});passport.use('oidc', new Strategy({ client,passReqToCallback: true}, (req, tokenSet, userinfo, done) => {
console.log("tokenSet",tokenSet);
console.log("userinfo",userinfo);
// do whatever you want with tokenset and userinfo req.session.tokenSet = tokenSet;
req.session.userinfo = userinfo;

return done(null, tokenSet.claims());
}));
});

8. Create routes for login, login callback

app.get('/login',(req, res, next) => {
console.log('-----------------------------');
console.log('Login Handler Started');
next();
},
passport.authenticate('oidc',{scope:"openid"}));
app.get('/login/callback',(req,res,next) =>
{
passport.authenticate('oidc',{
successRedirect: '/user',
failureRedirect: '/' })
(req, res, next)
})

create home route and /user route

app.get("/",(req,res) =>{
res.send(" <a href='/login'>Log In with OAuth 2.0 Provider </a>")
})app.get ("/user",(req,res) =>{res.header("Content-Type",'application/json'); res.end(JSON.stringify({tokenset:req.session.tokenSet,userinfo:req.session.userinfo},null,2));})

9. So Our Final index.js will be like this

10 . Run index.js to start server

nodemon index.js

11 . Go to http://localhost:8080 on browser. and click on “Log in with OAuth 2.0 Provider”

12. You will be redirected to OAuth Provider Login Page. As I am using prevoiusly created oidc-provider which is running on http://localhost:3000/oidc so it will take me following page

put any random username and password.

After you continue it will redirect us to client redirect url

Voilla..!! You got access_token

How to get userinfo from this access_token ?

Copy access_token and and go to postman and make a post request with this access_token to userinfo endpoint (you can get this endpoint in .well-known/openid-configuration of provider).

put access_token in x-www-form-urlencoded and send, you will get userinfo in response.

--

--