reactjs - Keycloak 仅保护特定路线 [客户端]
问题描述
我已经用我的 ReactJS 应用程序实现了 keycloak 身份验证。目前我所有的路线都通过以下方式得到保障。
keyCloak.init({
onLoad: 'login-required',
checkLoginIframe: false
}).success(authenticated => {
if (authenticated) {
ReactDOM.render(Application, document.getElementById('root'));
}
});
我仅在身份验证成功时才呈现反应应用程序。但是现在我需要一些不需要密钥斗篷身份验证的公共路径,任何用户都可以去检查。有没有适当的方法来实现这一目标?
解决方案
安装@react-keycloak/web 库
前置要求: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
中看到的那样,没有第一个参数,因为我们不需要使用该 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();
}
此外,还有另一种限制其他包装组件的方式,如下例所示。(带有包装组件)
推荐阅读
- python - re.search "TypeError: 预期的字符串或类似字节的对象"
- c - 递归函数 C?
- flutter - isEmpty 在 null 上被调用
- pyspark - 侧视图爆炸奇怪行为
- python - Python:在同一行中声明多个变量的类型
- python - 如何修复:“测试 pyext 配置:无法构建 python 扩展”
- python - 如何在 Python 中使用 Tensorflow 2 求解 ODE?
- java - 如何使用 java11 在 FXML 中使用 javaFX 类型的代码推荐器?
- java - Spring Data MongoDB 标识符作为对象
- swift - 快速在自定义框架中添加 facebook 和 google 登录