I’m using Keycloak in React to authenticate users, when I use <React.StrictMode> I get the following error:
Failed to initialize adapter: Error: A ‘Keycloak’ instance can only be initialized once.
First, I defined the Keycloak instance in component and at the highest level and outside of useEffect.
Then I created the Keycloak config in a separate file as below and inserted it into component, still the problem persists.
Keycloak config file
import Keycloak from 'keycloak-js';
const keycloakConfig = {
url: 'http://192.168.12.231:8080/auth/',
realm: 'MyRelm',
clientId: 'client',
};
const keycloak = new Keycloak(keycloakConfig);
export default keycloak;
component
import React, { useState, useEffect } from "react";
import { NavLink, Outlet } from "react-router-dom";
import keycloak from "../keycloakConfig";
import { jwtDecode } from "jwt-decode";
function Management() {
const [authenticated, setAuthenticated] = useState(false);
const [userRoles, setUserRoles] = useState([]);
const [fullName, setFullName] = useState('');
useEffect(() => {
const initKeycloak = async () => {
try {
const authenticated = await keycloak.init({ onLoad: 'check-sso', initOptions: { pkceMethod: 'S256', checkLoginIframe: false } });
console.log(`User is ${authenticated ? 'authenticated' : 'not authenticated'}`);
setAuthenticated(authenticated);
if (authenticated) {
const token = keycloak.token;
const decodedToken = jwtDecode(token);
const roles = decodedToken.realm_access.roles;
const name = decodedToken.name
setUserRoles(roles);
setFullName(name);
}
} catch (error) {
console.error('Failed to initialize adapter:', error);
}
};
initKeycloak();
}, []);
const handleLogout = () => {
keycloak.logout();
};
const handleLogin = () => {
keycloak.login();
};
return (
<div className="panel app">
<div className="sidebar">
<NavLink to={"/"}> Welcome ! </NavLink>
<NavLink to={"/managment"}> Project Information </NavLink>
<NavLink to={"managment/user"}> User </NavLink>
<NavLink to={"managment/groups"}> Groups </NavLink>
</div>
<div className="content">
{authenticated ? (
<Outlet />
) : (
<p>You do not have permission to access this content!</p>
)}
</div>
<div className="user-info">
{authenticated ? (
<>
<h3>{fullName}</h3>
<h5>User Roles:</h5>
<ul>
{userRoles.map((role, index) => (
<li key={index}>{role}</li>
))}
</ul>
<button className="logOut" onClick={handleLogout}>Log Out</button>
</>
) : (
<button className="logOut" onClick={handleLogin}>Log In</button>
)}
</div>
</div>
);
}
export default Management;
I’m using Keycloak in React to authenticate users.
2
Answers
I think I found the answer to my question in the following post. https://stackoverflow.com/a/72585970/9897918
In Strict.Mode, the problem was solved in the following way
I created a useRef variable and set its value to false
I checked the defined variable before initialization Keycloak
If the value of the variable is false, I True it and do init
The above code was edited as follows