ExpressJS— User Authentication with Asgardeo

Dimuthu Kasun
Identity Beyond Borders
7 min readJun 9, 2022

When implementing applications with NodeJS/Express framework, sometimes we may have a requirement to implement user authentication/authorization modules for our use cases. In this case, developers need to give additional effort to implement authentication modules.

Implementing an authentication module is not easy as we need to maintain the best security practices and standard protocols to authenticate users. In this case, Identity Providers come into the picture.

Why do we need an Identity Provider?

An Identity Provider (IdP) is capable of managing digital identities in a secure manner. You can integrate your applications with an identity provider to authenticate users and obtain identification information by using security tokens like SAML 2.0, OpenID Connect, OAuth 2.0, and WS-Trust.

Also, it is hard to build an IAM solution in-house, and stay in compliance with regulatory requirements when handling users. So we can use an identity provider to solve and keep the development simple.

Asgardeo as your Identity Provider

Asgardeo is an Identity as a Service (IDaaS) by WSO2. You don’t need to be an identity expert to implement authentication to your website/application. You can simply register and start using Asgardeo to integrate secure user login to your website/application. You can register to Asgardeo for free from here. If you already have an account, sign in from here.

In this article, Let’s discuss how to authenticate users in Express Framework-based applications using Asgardeo Express SDKs. I will use OpenID Connect as the authentication protocol.

Create a Standard-Based Application in Asgardeo Console with OpenID Connect as the protocol.

We need to create a standard-based application in Asgardeo as it is required to initiate authentication flow with Asgardeo using the authorization_code grant type.

  • Enter a name for the application and select OAuth2.0 OpenID Connect as the protocol. Click Register.
  • You will be redirected to the application page. you can find the client_id and client_secret from the protocol tab.
  • Select code from the Allowed grant types list as we need the authorization_code grant for the authentication flow.
  • Add below Redirect URL as Authorized redirect URL to the application. More information about these Redirect URLs can be found here. As my application is running locally on port 3000, I have set the host as lcoalhost and port as 3000 .
http://localhost:3000/login
http://localhost:3000/logout
  • Click on the Update button at the bottom of the page.

NodeJS User Authentication with Asgardeo

If you are using Nodejs without any framework or any framework other than ExpressJS, you can use Asgardeo NodeJS SDK to easily integrate user authentication into your application.

You can find a sample application with Asgardeo NodeJS integration here. As mentioned earlier, this tutorial is about ExpressJS applications. So Let’s get back to business :) .

ExpressJS User Authentication with Asgardeo

Let’s discuss how to integrate Asgardeo Express SDK with your existing Express application. For this, I will use a sample Express application for demonstration. You can also set up this sample application and follow the steps if you don’t have any existing Express application.

  • Install Asgardeo ExpressJS SDK dependency. Go to the project directory and run one of the commands below.
npm install @asgardeo/auth-express
  • Create src/config.json file to store the Asgardeo application related configurations. You can find more information here.
{
"clientID":"",
"clientSecret":"",
"baseUrl":"https://api.asgardeo.io/t/<org_name>",
"appURL":"http://localhost:3000",
"scope":["openid", "profile"]
}
  • Edit the index.js file. Here we have to implement the below functionalities.
    i. Configure AsgardeoExpressClient.
    ii. Configure asgardeoExpressAuth middleware.
    iii./home route and data handling.

i. Configure AsgardeoExpressClient.

const { AsgardeoExpressClient } = require("@asgardeo/auth-express");const config = require("./config.json");AsgardeoExpressClient.getInstance(config);

As you see here, we can get the AsgardeoExpressClient module and initialize an instance by passing the configuration as the parameter for the getInstance method.

ii. Configure asgardeoExpressAuth middleware.

const onSignIn = (res) => {
res.redirect("/home");
}
const onSignOut = (res) => {
res.redirect("/");
}
const onError = (res, error) => {
res.redirect(
url.format({
pathname: "/",
query: {
message: error && error.message
}
})
);
}
app.use(AsgardeoExpressClient.asgardeoExpressAuth(onSignIn, onSignOut, onError));

AsgardeoAuth middleware provides methods to implement authentication. Here we can pass the above three methods that have the redirection paths for each authentication action(login, logout, error).

We can use this middleware to initiate the AsgardeoAuth for your application. By default, /login and /logout routes will be available to do the authentication OOTB. So as soon as you initialize the asgardeoAuth middleware, the /login and /logout routes will be available out of the box.

iii. /home route and data handling.

This application has a second page and let’s call it the home page. Users will be redirected to the home page after successful authentication and we will implement this /home route as a protected route where only authenticated users can access the home page.

app.use("/home", express.static("static"));const authCallback = (res, error) => {
res.redirect(
url.format({
pathname: "/",
query: {
message: error
}
})
);
return true;
};
const dataTemplate = {
authenticateResponse: null,
error: false,
errorMessage: "",
idToken: null,
isAuthenticated: true,
isConfigPresent: Boolean(config && config.clientID && config.clientSecret)
};
const isAuthenticated = AsgardeoExpressClient.protectRoute(authCallback);app.get("/home", isAuthenticated, async (req, res) => {
const data = { ...dataTemplate };
try {
data.idToken = data.isAuthenticated
? await req.asgardeoAuth.getIDToken(req.cookies.ASGARDEO_SESSION_ID)
: null;
data.authenticateResponse = data.isAuthenticated
? await req.asgardeoAuth.getBasicUserInfo(req.cookies.ASGARDEO_SESSION_ID) : {};
data.error = req.query.error === "true"; res.render("homePage", data);
} catch (error) {
res.render("homePage", { ...data, error: true });
}});

To serve our CSS, images in the static directory of our sample application, we can use express.static("static") with our route /home .

As we are implementing our Home page as a protected page/route, we can use protectRoute middleware in Asgardeo Express SDK. Here we have to pass the unauthenticatedCallback method to the protectRoute. This method is used to handle the callback from a protected route.

ProtectRoute will return whether the user is already authenticated or not. Based on that we can implement home route logic as in the above code snippet. Here dataTemplate is the place we are keeping the all required information about the authentication/SDK.

Also, Asgardeo Express SDK is providing getIDToken() and getBasicUserInfo()to get the ID token details and basic user information details after authentication is successful.

Full index.js file can be found here.

  • Implement the Login button action.

Let’s implement what should happen when the Login button is clicked. We just need to wrap the login button with a form element where /login will be the action of that form. As I mentioned earlier, AsgardeoAuth middleware in the SDK will handle all the logic when we are on the /login route.

<form action="/login">                                                                     <button class="btn-custom" type="submit">Login with                                                        Asgardeo
</button>
</form>

Other than the above implementation, I will implement the logic to check whether the clientID & clientSecret values are specified in the config.json file. If clientID & clientSecret values are not specified, it will show an error on our landing page. If any authentication error occurs in the authentication process, it will also display an error.

As you can see in the above code, isConfigPresent,error variables are defined in the index.js file and they are passed to this page using the res.render() method.

The full landing page implementation can be found here.

  • Implementing the home page.

As we are storing the Idtoken , authenticationResponse values in dataTemplate object from index.js file, we can access them and display them on our home page.

For the logout button, we just need to wrap the logout button with a form element where /logout will be the action of that form. As I mentioned earlier, AsgardeoAuth middleware in the SDK will handle all the logic when we are on the /logout route.

<form action="/logout">                                        <button class="btn-custom" type="submit">Logout</button>                                    </form>

The full Home page implementation can be found here.

Some other APIs in Asgardeo Express SDK

  1. getOIDCServiceEndpoints
getOIDCServiceEndpoints(): Promise<OIDCEndpoints>

This method returns the OIDC service endpoints obtained from the .well-known endpoint. More Information can be found here.

2. getAccessToken

getAccessToken(userId?: string): Promise<string>

This method will return the AccessToken. userId parameter is optional.

3. updateConfig

auth.updateConfig({
signOutRedirectURL: "http://localhost:3000/sign-out"
});

This method can be used to update the configurations dynamically that passed into the constructor of the AsgardeoExpressClient while initializing the AsgardeoExpressClient.

You can find all the APIs in Asgardeo Express SDK from here.

Summary

So far we have completed,

  • Create a standard-based application in Asgardeo console
  • How to integrate Asgardeo Express SDK to an existing Express application
  • Implement Login button functionality
  • Implement Logout button functionality
  • Sample APIs in the Asgardeo Express SDK

Finally, We have one remaining task. That is to run our application :).

npm run serve

Open the application by accessinghttp://localhost:3000 on the browser and logging in to the application using Asgardeo.

Hope you have gained some knowledge on how to authenticate users with Asgardeo in the NodeJS & ExpressJS applications using the Asgardeo Express SDK and NodeJS SDK.

You can find the source code with all the functionalities described above below.

Thank you for reading this article.

Cheers!

--

--