Я пытаюсь защитить реагирующий компонент с помощью keycloak, и до сих пор я делал все, как он сказал:
но в конце я получаю эту ошибку:
keycloak.init(...).then is not a function
Я пытался заменить login-required на check-sso
вот мой код, введенный в мой компонент:
import Keycloak from 'keycloak-js';
componentDidMount() {
const keycloak = Keycloak('./public/keycloak.json');
keycloak.init({onLoad: 'login-required'}).then(authenticated => {
this.setState({ keycloak: keycloak, authenticated: authenticated })
})
}
render(){
if (this.state.keycloak) {
if (this.state.authenticated)
return (<div className = "container text-dark">);
else return (<div>Unable to authenticate!</div>)
}
return (<div>Initializing Keycloak...</div>);
}






Пожалуйста, проверьте, что keycloak.json содержит следующие значения: -
{
"realm": "...",
"auth-server-url": "http://...",
"ssl-required": "none",
"resource": "...",
"public-client": true,
"confidential-port": 0
}
это мой keycloak.json { "realm": "insapi", "auth-server-url": "локальный хост: 8080/аутентификация", "ssl-required": "external", "resource": "simulgarantie", "public-client" : true, "конфиденциальный порт": 0 }
@Samar, пожалуйста, проверьте "ssl-required":"none", так как auth-server-url является локальным хостом, а сертификат ssl не добавлен
Все та же ошибка, функция init неизвестна, я думаю, есть адаптер javascript, который я должен где-то добавить
Вместо :
const keycloak = Keycloak('./public/keycloak.json');
Попробуй это:
const keycloak = Keycloak('/keycloak.json');
и установите тип обещания в родной в параметрах инициализации следующим образом (в вашем случае):
keycloak.init({onLoad: 'login-required', promiseType: 'native'}).then(authenticated => {
this.setState({ keycloak: keycloak, authenticated: authenticated })
})
Это может вам помочь, но реализовано с другой библиотекой, но вы можете ограничить React Routes/Component/Functions
Установите @react-keycloak/веб-библиотеку
Предварительно требуется: keycloak-js 9.0.2 или новее
npm install --save keycloak-js
npm install --save @react-keycloak/web
Создайте файл keycloak.js в папке src вашего проекта со следующим содержимым, чтобы при необходимости настроить экземпляр Keycloak.
Настройте экземпляр Keycloak
import Keycloak from 'keycloak-js'
const keycloakConfig = {
url: 'http://localhost:8080/auth',
realm: 'Demo',
clientId: 'react-app'
}
const keycloak = new Keycloak(keycloakConfig);
export default keycloak
Затем оберните свое приложение внутри KeycloakProvider и передайте экземпляр keycloak в качестве реквизита.
import React from 'react';
import { KeycloakProvider } from '@react-keycloak/web'
import keycloak from './keycloak'
import AppRouter from './routes'
const App = () => {
return (
<KeycloakProvider keycloak = {keycloak}>
<AppRouter/>
</KeycloakProvider>
)
}
Как вы видите, в AppRouter компонент useKeycloak используется без 1-го параметра, потому что нам не нужно использовать этот объект экземпляра keycloak. Но второй параметр initialized используется, потому что PrivateRoute использует экземпляр keycloak, а объект keycloak должен быть доступен при инициализации PrivateRoute, это означает, что до инициализации keycloak маршруты не могут быть возвращены
import { useKeycloak } from '@react-keycloak/web';
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import Menu from '../components/Menu';
import HomePage from '../pages/HomePage';
import { PrivateRoute } from '../utilities/PrivateRoute';
import ProtectedPage from '../pages/ProtectedPage';
export const AppRouter = () => {
const [, initialized] = useKeycloak();
if (!initialized) {
return <h3>Loading ... !!!</h3>;
}
return (<>
<Menu />
<BrowserRouter>
<Switch>
<Route exact path = "/" component = {HomePage} />
<PrivateRoute roles = {['RealmAdmin']} path = "/protected" component = {ProtectedPage} />
</Switch>
</BrowserRouter>
</>
);
};
Создайте файл PrivateRoute.js в папке src/utilities вашего проекта со следующим содержимым.
import { useKeycloak } from '@react-keycloak/web';
import React from 'react';
import { Redirect, Route } from 'react-router-dom';
export function PrivateRoute({ component: Component, roles, ...rest }) {
const [keycloak] = useKeycloak();
const isAutherized = (roles) => {
if (keycloak && roles) {
return roles.some(r => {
const realm = keycloak.hasRealmRole(r);
const resource = keycloak.hasResourceRole(r);
return realm || resource;
});
}
return false;
}
return (
<Route
{...rest}
render = {props => {
return isAutherized(roles)
? <Component {...props} />
: <Redirect to = {{ pathname: '/', }} />
}}
/>
)
}
Давайте посмотрим, как ограничить компоненты/функции с помощью Keycloak.
import { useKeycloak } from '@react-keycloak/web';
export default function AuthorizedFunction(roles) {
const [keycloak, initialized] = useKeycloak();
const isAutherized = () => {
if (keycloak && roles) {
return roles.some(r => {
const realm = keycloak.hasRealmRole(r);
const resource = keycloak.hasResourceRole(r);
return realm || resource;
});
}
return false;
}
return isAutherized();
}
Кроме того, есть еще один способ ограничения с помощью компонента-обертки пыльника, как показано ниже. (с компонентом-оболочкой)
привет, один вопрос по этому поводу, когда я начинаю использовать веб-приложение, щелкая URL-адреса с частного маршрутизатора, перед каждой страницей я вижу «Загрузка», как это изменить? Спасибо
Keycloak теперь использует .success() для разрешенного обещания и .error() для отклоненного обещания, когда запускается keycloak.init()
const keycloak = Keycloak({
"clientId": "...",
"realm": "...",
"url": "...",
"ssl-required": "...",
"credentials": {
"secret": "...1"
},
"enable-cors": true,
"public-client": true,
"confidential-port": 0
});
keycloak.init({ onLoad: 'login-required' }).success(authenticated => {
this.setState({ keycloak, authenticated: authenticated },loadData)
})
Похоже, вы используете более старую версию Keycloak, success устарела в пользу then. См. руководство для справки: keycloak.org/docs/latest/securing_apps/#_javascript_adapter
да, спасибо за указание на это .. это для более старой версии
Пожалуйста, укажите вашу ошибку в текстовом формате непосредственно в вопросе вместо ссылки на внешнее изображение.