# ReactJs

**Software Name:** Galaxy ID

**Software Version:** 0.1

### Acronyms and Terms

<table data-header-hidden><thead><tr><th width="150"></th><th width="150"></th><th></th></tr></thead><tbody><tr><td><strong>No.</strong></td><td><strong>Words</strong></td><td><strong>Descriptions</strong></td></tr><tr><td>1</td><td>GID</td><td>Galaxy ID</td></tr><tr><td>2</td><td>SSO</td><td>Single Sign-On</td></tr><tr><td>4</td><td>Client</td><td>An application that integrates for GID</td></tr></tbody></table>

### Summary

Galaxy ID is an SSO system. It provides endpoints that enable clients to authenticate and authorize in many places.

### Integrate

#### Setting up our React frontend

First, create a new React app.

Install `keycloak-js`, `@react-keycloack/web`, and `react-router-dom`

```
npm install --save keycloak-js @react-keycloak/web react-router-dom
```

Keycloak and `@react-keycloak/web` will be used for the React-Keycloak implementation, while React Router DOM will be used for creating our pages. Please note that this tutorial was created using [React Router v6](https://blog.logrocket.com/react-router-v6/).

Next, add two folders named `components` and `pages` to your `src` folder. Add a `Homepage.js` file and a `Securedpage.js` file to the `pages` folder, and add a `Nav.js` file to the `components` folder.

Add the following code to the `components/Nav.js` file:

```
import React from "react";

const Nav = () => {
 return (
   <div>
     <div className="top-0 w-full flex flex-wrap">
       <section className="x-auto">
         <nav className="flex justify-between bg-gray-200 text-blue-800 w-screen">
           <div className="px-5 xl:px-12 py-6 flex w-full items-center">
             <h1 className="text-3xl font-bold font-heading">
               Keycloak React AUTH.
             </h1>
             <ul className="hidden md:flex px-4 mx-auto font-semibold font-heading space-x-12">
               <li>
                 <a className="hover:text-blue-800" href="/">
                   Home
                 </a>
               </li>
               <li>
                 <a className="hover:text-blue-800" href="/secured">
                   Secured Page
                 </a>
               </li>
             </ul>
             <div className="hidden xl:flex items-center space-x-5">
               <div className="hover:text-gray-200">
                 <h1>Login</h1>
               </div>
             </div>
           </div>
         </nav>
       </section>
     </div>
   </div>
 );
};

export default Nav;
```

And add the following to the `pages/Homepage.js` file.

```
import React from 'react';


const Home = () => {

 return (
   <div>
     <h1 className="text-green-800 text-4xl">Welcome to the Homepage</h1>
   </div>
 );
};

export default Home;
```

Add the following to the `pages/Securedpage.js` file.

```
import React from 'react';


const Secured = () => {

 return (
   <div>
     <h1 className="text-black text-4xl">Welcome to the Protected Page.</h1>
   </div>
 );
};

export default Secured;
```

Update your `App.js` code with the following code.

```
import React from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Nav from "./components/Nav";
import WelcomePage from "./pages/Homepage";
import SecuredPage from "./pages/Securedpage";

function App() {
 return (
   <div>
     <Nav />
     <BrowserRouter>
       <Routes>
         <Route exact path="/" element={<WelcomePage />} />
         <Route path="/secured" element={<SecuredPage />} />
       </Routes>
     </BrowserRouter>
   </div>
 );
}

export default App;
```

The frontend file structure should look similar to this:

![](https://1930214686-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbUKOjSCaQIWsQBbFfX8V%2Fuploads%2FuNez9ecbAQfX2TN72smM%2Fimage%20\(2\).png?alt=media\&token=40d1e311-6a61-4581-b827-63b73da1f5ac)

#### Setting up Keycloak in React

After the React frontend is completely implemented, the next step is to configure Keycloak in the React project.

Create a file named `Keycloak.js` in your `src` folder and add the following code to it.

```
import Keycloak from "keycloak-js";
const keycloak = new Keycloak('<path to keycloak.json>');

export default keycloak;
```

`keycloak.json` (will be provided by admin):

```
{
  "realm": "demo",
  "auth-server-url": "https://gid-stg.demoapp.info/",
  "ssl-required": "external",
  "resource": "gid-client",
  "public-client": true,
  "confidential-port": 0
}
```

Update your `App.js` code to this:

```
import React from "react";
import { ReactKeycloakProvider } from "@react-keycloak/web";
import keycloak from "./Keycloak"
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Nav from "./components/Nav";
import WelcomePage from "./pages/Homepage";
import SecuredPage from "./pages/Securedpage";

function App() {
 return (
   <div>
     <ReactKeycloakProvider authClient={keycloak}>
       <Nav />
       <BrowserRouter>
         <Routes>
           <Route exact path="/" element={<WelcomePage />} />
           <Route path="/secured" element={<SecuredPage />} />
         </Routes>
       </BrowserRouter>
       </ReactKeycloakProvider>
   </div>
 );
}

export default App;
```

This code imports `<ReactKeycloakProvider />` and wraps the entire app with the provider. We also added our `keycloak.js` file as a prop.

#### Setting up React `ProtectedRoute`

In this step, we will create a protected route that can only be accessed by authenticated users. Create a `helpers` folder, and add a `PrivateRoute.js` file to it. Add the following code to the `helpers/PrivateRoute.js` file.

```
import { useKeycloak } from "@react-keycloak/web";

const PrivateRoute = ({ children }) => {
 const { keycloak } = useKeycloak();

 const isLoggedIn = keycloak.authenticated;

 return isLoggedIn ? children : null;
};

export default PrivateRoute;
```

This code checks if a user trying to access a protected route is authenticated, and either displays the protected route when a user is authenticated, or displays nothing if the user is unauthenticated.

Keycloak’s JavaScript adapter provides access to some additional properties for securing your application, such as the `authenticated` property, which we will be using to check if a user is authenticated. You can [view the other available properties](https://www.keycloak.org/docs/latest/securing_apps/index.html#properties) in the Keycloak docs.

Update the routes in your `App.js` file. We wrapped our `SecuredPage` route with the protected route we created; this will ensure that the contents of `SecuredPage` can only be accessed by authenticated individuals.

```
import React from "react";
import { ReactKeycloakProvider } from "@react-keycloak/web";
import keycloak from "./Keycloak";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import Nav from "./components/Nav";
import WelcomePage from "./pages/Homepage";
import SecuredPage from "./pages/Securedpage";
import PrivateRoute from "./helpers/PrivateRoute";

function App() {
 return (
   <div>
     <ReactKeycloakProvider authClient={keycloak}>
       <Nav />
       <BrowserRouter>
         <Routes>
           <Route exact path="/" element={<WelcomePage />} />
           <Route
             path="/secured"
             element={
               <PrivateRoute>
                 <SecuredPage />
               </PrivateRoute>
             }
           />
         </Routes>
       </BrowserRouter>
     </ReactKeycloakProvider>
   </div>
 );
}

export default App;
```

We have now added a new login/logout button. The code checks if a user is authenticated and displays the **Login** button when the user has been authenticated, and a **Logout** button when the user has not been authenticated.

When the **Login** button is clicked, it calls Keycloak’s [`Login method`](https://www.keycloak.org/docs/latest/securing_apps/index.html#login-options) to authenticate the user. When the **Logout** button is clicked, it calls the [`Logout method`](https://www.keycloak.org/docs/latest/securing_apps/index.html#logout-options) to log the user out.

When you visit the demo React website we created, there should now be a **Login** button on the navbar. Also, the secured page should display nothing if you try to access it.

![](https://1930214686-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbUKOjSCaQIWsQBbFfX8V%2Fuploads%2F5DNVSKPaFW0K6OQamNv2%2Fimage%20\(3\).png?alt=media\&token=860d54ba-b968-4080-9edf-6cfdb50d218e)

When you click the **Login** button, you should be redirected to a Galaxy ID login page.

<figure><img src="https://1930214686-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbUKOjSCaQIWsQBbFfX8V%2Fuploads%2FtbnFLQvXjhAN1Dqa7gSL%2Fimage.png?alt=media&#x26;token=16d4af60-8a8b-46ae-8e8e-fe8246201ebf" alt=""><figcaption></figcaption></figure>

#### Get user information

* With the access token, we can get user info with *tokenParsed* property: *keycloak.tokenParsed* (recommend).

![](https://1930214686-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FbUKOjSCaQIWsQBbFfX8V%2Fuploads%2FocNsTpViI8uRzq2o7jSO%2Fimage%20\(1\).png?alt=media\&token=a6564951-c424-419c-a4db-ae881266f1af)

* With RESTful API:

**URL**: \<host>/realms/\<realmName>/protocol/openid-connect/userinfo

**Method**: GET

**Header**: Authorization: Bearer \<access token>

Example request:

```
curl --location --request GET 'https://gid-stg.demoapp.info/realms/demo/protocol/openid-connect/userinfo' \
--header 'Authorization: Bearer <access token>'
```

Example response:

```
{
    "sub": "3d83889f-297f-4283-8602-73c6b60630be",
    "email_verified": false,
    "name": "Duy Doan",
    "preferred_username": "+84391234567",
    "given_name": "Duy",
    "family_name": "Doan",
    "email": "duydoan@gmail.com"
}
```

* [How to implement Keycloak authentication in React - LogRocket Blog](https://blog.logrocket.com/implement-keycloak-authentication-react/)
* <https://github.com/keycloak/keycloak-documentation/blob/main/securing_apps/topics/oidc/javascript-adapter.adoc>
