基于Keycloak认证时如何处理URI重定向(Node.js+UI5技术栈)
Keycloak + Node.js(后端) + UI5(前端) 身份认证实现方案
你这个场景用OAuth2授权码流实现即可,keycloak-connect官方库已经封装了重定向、令牌校验的核心逻辑,不需要自己重复造轮子,以下是分步配置说明:
一、后端(Node.js+Express)核心配置
1. 依赖安装
首先安装官方适配包和session依赖:npm install keycloak-connect express-session
生产环境建议把默认的内存session换成Redis等持久化存储,避免重启丢登录态。
2. Keycloak实例初始化&路由拦截
示例代码如下,配置项可以直接从Keycloak控制台对应客户端的「安装」页下载的keycloak.json里复制:
const session = require('express-session'); const Keycloak = require('keycloak-connect'); const express = require('express'); const app = express(); // 配置session存储 const memoryStore = new session.MemoryStore(); app.use(session({ secret: '自定义的session加密密钥', resave: false, saveUninitialized: true, store: memoryStore, cookie: { maxAge: 24 * 60 * 60 * 1000 } // 登录态有效期1天,可自行调整 })); // 初始化Keycloak实例 const keycloak = new Keycloak({ store: memoryStore }, { realm: '你创建的Realm名称', 'auth-server-url': '你的Keycloak服务访问地址', resource: '你创建的客户端ID', credentials: { secret: '客户端密钥,在Keycloak客户端的「凭证」页获取' }, 'verify-token-audience': true, // 开启受众校验,防止令牌冒用 'confidential-port': 0 }); // 挂载Keycloak中间件,自定义异常跳转路径 app.use(keycloak.middleware({ logout: '/logout', // 自定义登出接口路径 accessDenied: '/unauthorized.html' // 权限不足时跳转的错误页 })); // 路由规则配置:需要认证的路径都套keycloak.protect()中间件 // 拦截所有API请求和UI页面请求 app.use(['/api/**', '/*.html'], keycloak.protect(), (req, res, next) => { // 这里可以直接拿到已认证用户的信息,做自定义的权限校验 // console.log('当前用户ID', req.kauth.grant.access_token.content.sub) // console.log('当前用户角色', req.kauth.grant.access_token.content.realm_access.roles) next(); }); // 公共路径排除:不需要认证的资源直接放行 app.use(express.static('./public', { extensions: ['html'] })); app.listen(3000, () => console.log('应用启动在3000端口'));
二、前端(UI5)适配配置
因为后端已经拦截了所有UI入口的请求,前端不需要做复杂的认证逻辑,只需要加一层路由钩子优化体验即可:
1. 路由跳转前校验
在UI5项目的Component.js的init方法里加路由前置拦截,避免用户手动输入路径时出现空白页:
sap.ui.define([ "sap/ui/core/UIComponent", "sap/ui/model/json/JSONModel" ], function(UIComponent, JSONModel) { "use strict"; return UIComponent.extend("你的应用命名空间.Component", { metadata: { manifest: "json" }, init: function() { UIComponent.prototype.init.apply(this, arguments); this.getRouter().initialize(); // 路由跳转前校验登录态 this.getRouter().attachBeforeRouteMatched(async () => { try { const res = await fetch("/api/user/current"); if (!res.ok) throw new Error("未认证"); // 把用户信息存到全局模型供业务使用 this.setModel(new JSONModel(await res.json()), "user"); } catch (e) { // 校验失败跳首页,后端会自动重定向到Keycloak登录页 window.location.replace("/index.html"); } }); } }); });
三、核心逻辑说明
1. 重定向&认证流程
keycloak.protect()中间件已经内置了完整的重定向逻辑:
- 未认证的请求进来后,会自动生成Keycloak的认证地址,返回302重定向到登录页
- 用户登录成功后,Keycloak会携带授权码回调你的应用,后端自动用授权码兑换access_token、refresh_token、id_token
- 令牌校验通过后存入session,自动重定向回用户最初请求的业务页面
- 权限不足时会自动跳转到你配置的
accessDenied路径
2. 令牌校验规则
不需要你自己写校验逻辑,keycloak-connect会自动完成以下校验,任意一项不通过都会判定为认证失败:
- 校验JWT签名是否和Keycloak的公钥匹配
- 校验令牌是否在有效期内
- 校验令牌的签发方是否是你的Keycloak实例
- 校验令牌的受众是否是你的客户端ID
3. 路由规则配置原则
- 后端侧:所有需要访问控制的资源(API接口、UI页面、私有静态资源)都挂载
keycloak.protect()中间件,公共资源(错误页、公共logo、免登说明页)排除即可 - 前端侧:不需要修改业务路由,只要保证所有前端入口都被后端拦截即可,路由前置钩子只是做体验优化,不做核心权限控制
内容的提问来源于stack exchange,提问作者Linkx_lair
相关产品推荐
相关产品推荐

