Попытка защитить страницу реагирования переднего плана с помощью сервера keycloak, но у меня есть эта ошибка «keycloak.init(...).then is not a function»

Я пытаюсь защитить реагирующий компонент с помощью keycloak, и до сих пор я делал все, как он сказал:

  • Я установил пакеты KEycloak через NPM
  • Я поместил keycloak.json в общую папку.
  • Я изменил свой компонент, чтобы он монтировался при маршрутизации страницы.

но в конце я получаю эту ошибку:

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, но у меня есть эта ошибка «keycloak.init(...).then is not a function»

Пожалуйста, укажите вашу ошибку в текстовом формате непосредственно в вопросе вместо ссылки на внешнее изображение.

Tholle 25.03.2019 13:20
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
3
1
9 269
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Пожалуйста, проверьте, что 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 25.03.2019 13:27

@Samar, пожалуйста, проверьте "ssl-required":"none", так как auth-server-url является локальным хостом, а сертификат ssl не добавлен

Avinash 25.03.2019 13:35

Все та же ошибка, функция init неизвестна, я думаю, есть адаптер javascript, который я должен где-то добавить

Samar 25.03.2019 13:44
Ответ принят как подходящий

Вместо :

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();
    }

Кроме того, есть еще один способ ограничения с помощью компонента-обертки пыльника, как показано ниже. (с компонентом-оболочкой)

https://medium.com/@cagline/authenticate-and-authorize-react-routes-component-with-keycloak-666e85662636

привет, один вопрос по этому поводу, когда я начинаю использовать веб-приложение, щелкая URL-адреса с частного маршрутизатора, перед каждой страницей я вижу «Загрузка», как это изменить? Спасибо

FrancMo 22.01.2021 14:32

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

jpoppe 25.11.2020 14:44

да, спасибо за указание на это .. это для более старой версии

codemon 23.02.2021 13:09

Другие вопросы по теме