OIDC Authentication for Express Apps with Asgardeo
Tags: javascript, express, wso2, asgardeo
Published: 2022-04-30 03:15:41

In my [previous article](https://dev.to/suvink/add-authentication-to-your-express-app-with-asgardeo-13bh), I discussed how we can use [Asgardeo Node SDK](https://www.npmjs.com/package/@asgardeo/auth-node) to add authentication to your Express app. As I mentioned before, the process of using the Node SDK in an Express app is not straightforward because the Node SDK is a generic SDK which is compatible across any Node JS platform. In this article, I will show you how you can use the Asgardeo Express SDK to add authentication to your Express app easily. 

TLDR;
Try the official sample app [here](https://github.com/asgardeo/asgardeo-auth-express-sdk/samples).  

**Prerequisites**  

- An Asgardeo organization. (You can create an organization upon registration at https://asgardeo.io/signup).
- A Standard Based Application - Once you create an organization in the Asgardeo Console, you can create a Standard Based Application from the dashboard. ([More info](https://wso2.com/asgardeo/docs/guides/applications/register-standard-based-app/)) 

**Projet Initialization**
Create a new directory (a folder) and open the directory using your code editor. Open a terminal and type `yarn init --y` and it will initialize a new project and create a `package.json` file. 

The next step is to install the dependancies.
```curl
yarn add @asgardeo/auth-express cookie-parser express
``` 
Then add Nodemon as a dev dependancy to hot reload your changes.
```curl
yarn add -D nodemon
```
Once you install Nodemon, modify the `package.json` and add `"serve": "nodemon server.js"` in the **scripts** section so we can use Nodemon to run the server. 

**Create an Express app**
Create a new file and name it as `server.js`.
Then create a simple express server inside your `server.js` file. You can use the code below.
```Javascript
const express = require('express');
const cookieParser = require('cookie-parser');

//Define the Port
const PORT = 5000;

//Initialize Express App
const app = express();
app.use(cookieParser());

app.get("/", (req, res) => {
    res.send("Hello World");
});

//Start the app and listen on the PORT
app.listen(PORT, () => { console.log(`Server Started at PORT ${ PORT }`); });
```
After creating the server, run it using,
```curl
yarn run serve
``` 
Now if you navigate to `http://localhost:5000`, you should see a "Hello World" response from the server.

**Add configuration for Asgardeo Authentication**
Create a new file in the directory and name it as `config.js`. Inside this file, you need to specify the configuration for the Asgardeo Auth. 
```javascript
const config = {
   clientID: "YOUR_CLIENT_ID",
   clientSecret: "YOUR_CLIENT_SECRET",
   baseUrl: "YOUR_BASE_URL",
   appURL: "http://localhost:5000",
   scope: ["openid", "profile"]
};
module.exports = config;
``` 
Replace the `clientID`, `clientSecret` and `baseUrl` from the values you get from [Asgardeo Console](https://console.asgardeo.io/). Since we run our server in `http://localhost:5000`, we have to add it as the appURL. 

**Note:**
Make sure you add `localhost:5000` as an allowed origin and add `localhost:5000/login` as an authorized redirect URL in the console. We will discuss why should we authorize `localhost:5000/login` endpoint specifically later on.  

**Use the AsgardeoAuth middleware**
Open the `server.js` file and import the middleware from the SDK.
```javascript
const { AsgardeoExpressClient } = require("@asgardeo/auth-express");
```
Then instantiate the Asgardeo Express client with the config we created earlier.
```javascript
AsgardeoExpressClient.getInstance(config);
```

Now you have to define three callback functions which are needed to initiate the middleware.

1. `onSignIn` - Handle a successful user sign in.
2. `onSignOut` - Handle a successful user sign out.
3. `onError` - Handle errors that might occur in the authentication process.

```javascript
const onSignIn = (res, response) => {
  if (response) {
    res.status(200).send(response);
  }else{
    res.status(500).send("Something went wrong");
  }
};

const onSignOut = (res) => {
  res.status(200).send("Sign out successful");
};

const onError = (res, error) => {
  if(error){
    res.status(400).send(error);
  }else{
    res.status(500).send("Something went wrong");
  }
};
```

After defining the callback functions, use the middleware with the Express app we created.
```javascript
app.use(
  AsgardeoExpressClient.asgardeoExpressAuth(onSignIn, onSignOut, onError)
);
```

That is all you have to do with the Express SDK to implement authentication. At this point, you can just navigate to `http://localhost:5000/login` and authenticate yourself. That brings me to explain why we added `localhost:5000/login` as an authorized redirect URL. The SDK itself is pre-configured to set the login endpoint to `/login` and to set the logout endpoint to `/logout`. So even though you didn't have to implement the logic for those 2 endpoints, you still need to authorize the endpoints in the console in order to function properly. 

In case you don't like the pre-configured login and logout paths, you can always override the defaults in the config file. All you have to do is add another property to the config object as follows.
```javascript
const config = {
   ...config,
   loginPath : "/customLogin",
   logoutPath: "/customLogout"
}
``` 
Don't forget to change the authorized redirect URL in the console if you're using a custom login and logout paths.

**Implementing Protected Routes**
In some use cases, you may want to protect a specific route with a login. To do this, Asgardeo Express SDK provides you with a simple middleware. All you have to do is, attach the `isAuthenticated` middleware to the route you want to protect.
```javascript
app.get("/protected", isAuthenticated, async (req, res) => {
    res.status(200).send({
        message: "Hello from protected route!"
    });
});
```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wfs13mapwvg3abym3yqg.jpeg)

The Asgardeo Express SDK has many features in addition to the basic login functions I described above. You can check them out at [Express SDK GitHub](https://github.com/asgardeo/asgardeo-auth-express-sdk) repo.  As always, feel free to reach me if you have any questions and you are welcome to [make contributions](https://github.com/asgardeo/asgardeo-auth-express-sdk/blob/main/pull_request_template.md) to the SDK as well. Thanks for reading!