So, I am working on a react-redux app which requires some users to authenticate, which I use keycloak for.
Basically there is a homepage thats public/not secured at:
- localhost:3000/
Now when the user clicks a link to go to the welcome page, the keycloak login page should popup and ask for authentication details, which I already managed to do:
- localhost:3000/welcome -> localhost:8080/auth
As stated above, the login page already shows up and correctly authenticates registered users. However, once successfully logged in, I am being redirected to localhost:3000/welcome (which is good), but without any content (which is not good).
So i went on to log the status of keycloak.authenticated to the console. Before calling "keycloak.init" it is undefined (which is fine), after successful authenticated it is false (:o?!?!).
Weird.
So it seems that i must manually change the status of keycloak.authenticated.
2 Questions: - how do i change keycloak.authenticated in the face of reduxish stateless components w/o constructors etc. - am i even right about my question?
Some formalities:
keycloak.js Code of the higher order component which the Welcome page is wrapped with:
import React from 'react';
const { Consumer, Provider } = React.createContext();
export const KeycloakProvider = Provider;
const withKeycloak = component =>
function WithKeycloak(props) {
return React.createElement(Consumer, null, keycloak => {
console.log('before: ', keycloak.authenticated); -> undefined
if (keycloak.authenticated) {
return React.createElement(component, { ...props, keycloak }, null);
}
console.log('before init: ', keycloak.authenticated); // -> undefined
keycloak.init({ onLoad: 'login-required' });
console.log('after: ', keycloak.authenticated); // -> false!!
return null;
});
};
export default withKeycloak;
main.jsx Code of main.jsx where keycloak is being defined:
/** @format */
import lots of stuff....;
import { KeycloakProvider } from './keycloak/provider';
import Keycloak from 'keycloak-js';
const store = ...
const keycloak = Keycloak({
url: 'http://localhost:8080/auth',
realm: 'Test-Jannis',
clientId: 'test-bayron'
});
const Main = () => (
<Provider store={store}>
<BrowserRouter>
<KeycloakProvider value={keycloak}>
<Route exact path="/" component={Home} />
<Route exact path="/welcome" component={WelcomePage} />
</KeycloakProvider>
</BrowserRouter>
</Provider>
);
export default Main;
My best guess would be to do something like this in under keycloak.init in keycloak.js:
keycloak.init({ onLoad: 'login-required' });
.then(authenticated => (keycloak.authenticated = authenticated));
But...that doesn't change keycloak.authenticated to be false.
Please help :)
UPDATE
Using the following code for keycloak.js:
const withKeycloak = component =>
function WithKeycloak(props) {
return React.createElement(Consumer, null, keycloak => {
console.log('before: ', keycloak.authenticated);
keycloak.init({ onLoad: 'login-required'}).success(function() {
if ( keycloak.authenticated ) {
console.log("return page: ", keycloak.authenticated);
console.log(component);
console.log(React.createElement(component, { ...props, keycloak }, null));
return React.createElement(component, { ...props, keycloak }, null);
}
console.log("return null: ", keycloak.authenticated);
return null;
});
});
};
Now outputs keycloak.authenticated === true! However, the redirected localhost:3000/welcome still doesn't display any of the html the welcome component is supposed to show.
Following KeyCloak JS adapter documentation:
By default, the JavaScript adapter creates a hidden iframe that is used to detect if a Single-Sign Out has occurred. This does not require any network traffic, instead the status is retrieved by looking at a special status cookie. This feature can be disabled by setting checkLoginIframe: false in the options passed to the init method.
You need to put your keycloak initialization code as:
keycloak.init({checkLoginIframe: false}).success((authenticated) => {
// Some stuff
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With