KeyCloakJS 使用
使用KeycloakJs来授权还是非常方便的,但是我们得首先了解授权码模式以及Pkce模式。
安装KeyCloak
可以利用docker安装Keycloak,详细可以参考这个官方进行配置 https://www.keycloak.org/getting-started/getting-started-docker
docker
docker pull keycloak/keycloak:22.0.4
docker run -p 8080:8080 -e KEYCLOAK_ADMIN=admin -e KEYCLOAK_ADMIN_PASSWORD=admin keycloak/keycloak start-dev
然后根据官方的参考进行配置
KeyCloakJs
首先我们应该有一个基础的前端应用。这里我们选择react。我们使用lerna_demo来构建我们的keycloak js
一、初始化 KeyCloakClient 类, 这里重点关注的是new Keycloak实例的配置以及init的配置。
KeyCloak实例化有三个参数
- clientId 配置的clientId
- realm 配置的realm
- url keycloak的url
KeyCloak init有以下配置
- onLoad 该配置有 check-sso 以及 login-required
check-sso 是隐式的检查是否登录,如果没登录不会跳转到登录页面
login-required 检查是否登录,如果没登录就会跳转到登录页面
redirectUri 跳转uri
silentCheckSsoRedirectUri 如果是check-sso的时候默认查询登录,然后设置登录状态
typescript
import Keycloak, {
KeycloakInitOptions,
KeycloakLoginOptions,
KeycloakLogoutOptions
} from 'keycloak-js'
export class KeycloakClient {
private _keycloakClient: Keycloak
constructor() {
this._keycloakClient = new Keycloak({
clientId: process.env.KEYCLOAK_CLIENT_ID!,
realm: process.env.KEYCLOAK_RELEAM!,
url: process.env.KEYCLOAK_URL
})
}
getKeyCloakClient(): Keycloak {
return this._keycloakClient
}
get authenticated() {
return this._keycloakClient.authenticated
}
get userInfo() {
return this._keycloakClient.userInfo
}
init(initOptions?: KeycloakInitOptions | undefined) {
return this._keycloakClient.init({
onLoad: 'check-sso',
...(initOptions ?? {})
})
}
createLoginUrl(options?: KeycloakLoginOptions | undefined) {
return this._keycloakClient.createLoginUrl(options)
}
logout = (options?: KeycloakLogoutOptions | undefined) => {
return this._keycloakClient.logout(options)
}
}
export const keyCloakClient = new KeycloakClient()
二、创建Login,Admin页面
创建Login页面,这里只有SSO登录,调用的是keyCloakClient的createLoginUrl,然后跳转
typescript
import React from 'react'
import Button from 'antd/es/button'
import { keyCloakClient } from '../keycloak'
export const LoginPage = () => {
const onClickLoginSSO = () => {
const url = keyCloakClient.createLoginUrl({
redirectUri: window.location.origin + '/'
})
window.location.assign(url)
}
return <Button onClick={onClickLoginSSO}>Login with SSO</Button>
}
创建Admin页面, 只包含LogoutButton 和 展示用户名
typescript
import React, { FC } from 'react'
import { LogoutButton } from '../login'
import { keyCloakClient } from '../keycloak'
export const Admin: FC = () => {
return (
<div>
Hello {keyCloakClient.getKeyCloakClient().idTokenParsed?.name ?? ''},
welcome vist admin page.
<LogoutButton />
</div>
)
}
三、配置路由
逻辑是如果访问根页面,判断是否登录,如果登录了,跳转admin,否则跳转login
同时如果直接访问admin,要判断是否已经登录,如果登录了可以跳转,否则提示未登录。
判断是否登录: keyCloakClient.authenticated
typescript
import React, { useMemo } from 'react'
import { createBrowserRouter, Navigate, RouterProvider } from 'react-router-dom'
import { LoginPage } from '../login'
import { Admin } from '../admin'
import { keyCloakClient } from '../keycloak'
import { ProtectedRouteElement } from './ProtectedRoute'
export const Routes = () => {
const router = useMemo(() => {
return createBrowserRouter([
{
path: '/',
element: keyCloakClient.authenticated ? (
<Navigate to='/admin' />
) : (
<Navigate to='/login' />
)
},
{
path: '/login',
element: <LoginPage />
},
{
path: '/admin',
element: (
<ProtectedRouteElement>
<Admin />
</ProtectedRouteElement>
)
}
])
}, [])
return <RouterProvider router={router} />
}
四、初始化keyCloak
typescript
keyCloakClient.init().finally(() => {
ReactDOM.render(<Index />, document.getElementById('content'))
})