keycloak登录-前端适配-vue & react

近期的项目用 keycloak 做统一登录的入口,前端登录页直接跳转 keycloak 登录,本篇基于 keycloak 26.3.2 版本,基于 vue & react 做适配。
后续:后端表示坑多,放弃这个选型。

登录-vue

window.APP_CONFIG.keyCloak = https://ip:port/realms/swsz/protocol/openid-connect/auth
window.APP_CONFIG.keyCloakToken = https://ip:port/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import Keycloak from 'keycloak-js'
import { useUserStore } from '@/store/modules/user'
import router from '@/router'

const userStore = useUserStore()

const goToKeycloak = () => {
// 跳转到Keycloak登录页面
// 这里需要根据你的Keycloak配置修改URL
const keycloakUrl = window.APP_CONFIG.keyCloak
const clientId = 'swbind' // 你需要在Keycloak中创建这个客户端
const redirectUri = encodeURIComponent(window.location.origin + '/login')
const responseType = 'code'
const authUrl = `${keycloakUrl}?client_id=${clientId}&redirect_uri=${redirectUri}&response_type=${responseType}&scope=openid`

window.location.href = authUrl
}

const initKeycloak = async () => {
const keycloak = new Keycloak({
url: window.APP_CONFIG.keyCloakToken,
realm: 'swsz',
clientId: 'swbind'
})

try {
const authenticated = await keycloak.init({
// checkLoginIframe: false,
onLoad: 'login-required'
})
if (authenticated) {
console.log('User is authenticated', authenticated)
if (keycloak.token) {
userStore.setToken(keycloak.token)
router.push('/')
}
} else {
console.log('User is not authenticated')
}
} catch (error) {
console.error('Failed to initialize adapter:', error)
}
}

onMounted(() => {
if (window.location.href.includes('code')) {
const code = window.location.href.split('code=')[1].split('#')[0]
console.log('code=', code)
initKeycloak()
} else {
goToKeycloak()
}
})

登录-react

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import Keycloak from 'keycloak-js';
import { useEffect } from 'react';

const Login = () => {
const goToKeycloak = () => {
const keycloakUrl = window.APP_CONFIG.keyCloak;
const clientId = 'swai';
const redirectUri = encodeURIComponent(window.location.origin + '/login');
const responseType = 'code';
const authUrl = `${keycloakUrl}?client_id=${clientId}&redirect_uri=${redirectUri}&response_type=${responseType}&scope=openid`;
window.location.href = authUrl;
};

const initKeycloak = async () => {
const keycloak = new Keycloak({
url: window.APP_CONFIG.keyCloak,
realm: 'swsz',
clientId: 'swai',
});

try {
const authenticated = await keycloak.init({
onLoad: 'login-required'
})
if (authenticated) {
console.log('User is authenticated', authenticated)
if (keycloak.token) {
authorizationUtil.setItems({
Token: keycloak.token
});
navigate('/');
}
} catch (error) {
console.error('Failed to initialize adapter:', error);
}
};

// 页面初始化时执行
useEffect(() => {
if (window.location.href.includes('code')) {
const code = window.location.href.split('code=')[1];
console.log('code=', code);
initKeycloak();
} else {
console.log('goToKeycloak');
goToKeycloak();
}
}, []);

return <div></div>;
};

export default Login;

附录
官方文档
前端接入keycloak的几种方式


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!