Coding Authentication? Stop now and let Choreo manage it.
Tags: webdev, authentication, wso2, react
Published: 2023-12-27 19:16:17

As a developer, you might have come across situations where you want to add authentication to a web app but it takes so much time/effort to do so writing all the code and managing protocols that you kind of wished there was an easy way. Well, Choreo's Managed Authentication lets you add authentication to your web app with a few clicks and a few lines of code easily. 

Let's see how.

_Note: Choreo's managed authentication is currently available only for React, Angular, and Vue.js web applications._

### Prerequisites

- A React app 
- A GitHub Account
- A Choreo Account ([Create an account here](https://console.choreo.dev/signup). It's FREE)
- Basic understanding of React JS

### Step 1: The Code

Once you enable Managed Authentication (which we will be doing in step 2), you need to redirect your application users to the respective login and logout paths for them to authenticate. 

#### Configure Login
To implement the login functionality, all you have to do is, redirect the user to the `/auth/login` path. Once redirected, Choreo will show a login form and users can use their credentials to log in.  

Let's implement this in a sample app. 

```javascript
import React from 'react';
import { Link } from "react-router-dom";

function App() {
  return (
    <div className="App">
      {/* Vanilla JS */}
      <button onClick={() => { window.location.href = "/auth/login" }}>Login</button>
      {/* React Router v6 */}
      <Link to="/auth/login">Login</Link>
    </div>
  );
}

export default App;
```
_If you are using React Router to handle navigation, you can use the respective navigation components offered by the React Router DOM. For this tutorial, we will be using vanilla JS._

#### Read user information

Once the user is logged in, you may need to access information like the user's name, email, etc. Choreo sends this information encoded in a cookie (named `userinfo`) upon successful login. We can extract the information using a cookie parsing library. For this example, we will be using [`js-cookie`](https://www.npmjs.com/package/js-cookie) library.

You can execute `npm i js-cookie` command from your terminal to install the library.

```javascript
import React, { useState, useEffect } from 'react';
import Cookies from 'js-cookie';

function App() {
  const encodedUserInfo = Cookies.get('userinfo');
  const [userInfo, setUserInfo] = React.useState(null);

  useEffect(() => {
    if (!encodedUserInfo) return;
    // Read the cookie and set it to the state.
    const userInfo = JSON.parse(atob(encodedUserInfo))
    if (userInfo) {
      const info = JSON.stringify(userInfo);
      localStorage.setItem('userinfo', info);
      setUserInfo(info);
      Cookies.remove('userinfo', { path: '/' })
    }
  }, [encodedUserInfo]);

  return (
    <div className="App">
      <button onClick={() => { window.location.href = "/auth/login" }}>Login</button>
    </div>
  );
}

export default App;
```
In this example code, first, we use the `js-cookie` library to read the `userinfo` cookie and then we set the information to the local state as well as to the local storage for persistence. After that, we clear the cookie (or biscuit if you're British). 

Now, at this point, we can modify our code a bit to show the user's username if authenticated and if not, we'll show the login button.

```javascript
import React, { useState, useEffect } from 'react';
import Cookies from 'js-cookie';

function App() {
  const encodedUserInfo = Cookies.get('userinfo');
  const [userInfo, setUserInfo] = React.useState(null);

  useEffect(() => {
    if (!encodedUserInfo) return;
    // Read the cookie and set it to the state.
    const userInfo = JSON.parse(atob(encodedUserInfo))
    if (userInfo) {
      const info = JSON.stringify(userInfo);
      localStorage.setItem('userinfo', info);
      setUserInfo(info);
      Cookies.remove('userinfo', { path: '/' })
    }
  }, [encodedUserInfo]);

  return (
     <div className="App">
      {
        userInfo ? <div>
          <h1>Welcome {userInfo.username}</h1>
        </div> :
          <button onClick={() => { window.location.href = "/auth/login" }}>Login</button>
      }
    </div>
  );
}

export default App;
```

#### Configure Logout

Similar to the login, we have to redirect the users to `auth/logout` path to log a user out. But for logout, we have to redirect the user with the session hint parameter which we can find in the `'session_hint` cookie. This cookie is also set when the user is successfully authenticated. Let's add that code to our example. 

```javascript
import React, { useState, useEffect } from 'react';
import Cookies from 'js-cookie';

function App() {
  const encodedUserInfo = Cookies.get('userinfo');
  const [userInfo, setUserInfo] = React.useState(null);

  useEffect(() => {
    if (!encodedUserInfo) return;
    // Read the cookie and set it to the state.
    const userInfo = JSON.parse(atob(encodedUserInfo))
    if (userInfo) {
      const info = JSON.stringify(userInfo);
      localStorage.setItem('userinfo', info);
      setUserInfo(info);
      Cookies.remove('userinfo', { path: '/' })
    }
  }, [encodedUserInfo]);

  const handleLogout = async () => {
    // Read the cookie
    const sessionHint = Cookies.get('session_hint');

    // Clear session data
    Cookies.remove('userinfo', { path: '/' })
    localStorage.clear();

    // Redirect the user
    window.location.href = `/auth/logout?session_hint=${sessionHint}`;
  }

  return (
    <div className="App">
      {
        userInfo ? <div>
          <h1>Welcome {userInfo.username}</h1>
          <button onClick={handleLogout}>Log Out</button>
        </div> :
          <button onClick={() => {
            window.location.href = "/auth/login"
          }}
          >
            Login
          </button>
      }
    </div>
  );
}

export default App;
```
To explain the `handleLogout` function, first, we read the `session_hint` cookie. Then we clear the user information we persisted in the browser for better security. Lastly, we direct the user to the `auth/logout` path with the session hint as a query parameter. 

🎉 Congratulations. Now you have an app with authentication enabled. Still, there's one more step to be done. 

### Step 2: Host the code on Choreo.

To complete this step, you need to have you source code committed to a GitHub (public) repository and you need to log into your Choreo Console. 

#### Create a WebApp Component

Once you are logged in to the Choreo Console, select the Web Application component and create a new web app.

![Choose the WebApplication Component from the Choreo Console](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/52mqsof3h9e9dw4zypqq.png)

Enter a name for the component and connect your GitHub repository to the component. From the buildpack section, choose "React" buildpack as we are creating a React Web App.

In the build configurations, input your build command (default: `npm run build`), build path (default: `/build`) and Node.js version. Finally, click on Create button.

![Web app creation settings](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9hzhuj4dexv1jkff9m1e.png)

#### Build the web application

After the component creation, navigate to the "Build" area of the Choreo Console.

![Use the left navigation bar to access the Build area](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g2j1d8ders0bgutui44i.png)

Click on Build, Choose the latest commit of your GitHub repository and build it. It will take some time for the application to be built so in the meantime, feel free to explore the Choreo Console and see what it can do for you!

![Follow these steps to build the app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6fjdw2q46spl6d9n6upj.png)

#### Deploy the web application

Once the web app is built, navigate to the Deploy area from the left navigation menu.

From the "Set up" area, click on "Configure & Deploy" button to deploy the web application. 

![Deploy the web app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iles76t7n9v5pabi8nei.png)

From the right drawer, just click next because we are not mounting any configurations for this web app and then you will see the Authentication step. You can already see that "Managed Authentication with Choreo" is enabled. 

In this menu, we have to configure the Post Login Path, Post Logout Path and the Error Path.

-  **Post Login Path** - The relative path that the application will be redirected to on successful sign-in. In our example, we used the same page to display the user's info as well as to handle login/logout. So we will use `/` as the Post Login Path.

- **Post Logout Path** - The relative path to which Choreo redirects you on successful sign-out. For the same reason as above, we will use `/` for this.

- **Error Path** - The relative path to which Choreo redirects you when an error occurs during a redirection. By default, Choreo has a built-in error page to display errors. So we can leave this blank and let Choreo take care of that. 

#### Configure Users

To test the authentication settings we implemented, we can quickly add a demo user in the same "Authentication Settings" step. Click on the Create button and you can create a demo user with a strong password. 

![Create the demo user](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2z9alad8s0ubhwmsrlx7.png)

After creating the demo user, click on the "Deploy" button to deploy the app. Again, it will take a moment for the app to get deployed. Once deployed, you can click on the Web App URL on the Development Environment card and explore the app we created. 

### Step 3: Try out a flow

Click on the login button on the application. It will redirect you to the `/auth/login` path and you can see Choreo's default login page.

![Choreo's default login page](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ism97ef908ay99es67di.png)

Add your demo user's credentials and click on "Sign In". After successful sign in, you will see "Welcome demouser" message and the logout button on the screen. 

### Add more users

When your app goes to production, you need to add more users than the demo user we created. To do that, go to the Choreo Console, navigate to Organization Settings > Application Security > Identity Providers and Click the "Manage" button on the "Choreo built-in Identity Provider". From there, you can download the CSV template for the users, fill it and upload it to the console.

That's it folks!

### Conclusion

In this tutorial, we implemented authentication functionality to a React JS web application using Choreo Managed Authentication. If you want to quickly start and experiment this feature, feel free to fork [this repository](https://github.com/Suvink/choreo-managed-auth-example) and deploy it on the Choreo Console. 

Choreo Managed Authentication can be used for more advanced scenarios and it has more features that we can user in an enterprise environment. We will discuss them in the next article. 

Until then, Happy Coding!