Keycloak 是一个优秀的开源身份与访问管理系统,旨在为现代的应用程序和服务提供包含身份管理和访问管理功能。不少企业包含红帽公司,都将其作为其站点的单点登录工具,通过使用 Keycloak,只需要少量编码甚至不用编码,就能很容易地使应用程序和服务更安全。



今天以 eggjs 为例子,展示只需要少量代码,便可以利用 Keycloak 来保护你的 eggjs 服务。eggjs 是一个基于 NodeJs 的优秀企业级应用框架,不少企业使用它构建自己的服务(我曾经服务过的一个创业公司,基本上所有服务都是一个 eggjs 实例)。

效果演示


请访问 https://uniheart.pa-ca.me/keycloak/login 体验。(请忍受比较慢的响应速度,因为服务器端使用了免费的服务,并且部署在国外

打开 https://uniheart.pa-ca.me/keycloak/login 链接,会自动跳转到 Keycloak 登录页面:
image.png

以上“微信”按钮,是按照《基于 keycloak 的关注公众号即登录功能的设计与实现》一文的介绍,实现的关注公众号即登录功能。推荐使用,因为更方便,但是仅对前 100 名用户有效,因为这是一个测试公众号,受此限制。


无论是通过邮箱/密码的方式,还是关注公众号的方式,登录完成后,会跳转回 **[https://uniheart.pa-ca.me/keycloak/login**](https://uniheart.pa-ca.me/keycloak/login)** 页面,目前这个页面只返回认证通过的 Keycloak 信息,比如:**
image.png

将 Keycloak 集成到 eggjs 的步骤

首先在 Keycloak 中新建一个 Realm

只需要取个名字就好:
image.png

然后在这个 Realm 中创建一个客户端

取一个名字,后面要用到。然后配置好你的 eggjs 服务所公开的终端节点(域名+路径),可以使用通配符。比如:
image.png

然后,在你的 eggjs 项目根目录下添加一个 keycloak.json 文件

内容如下,注意相关字段要和 Keycloak 对应。realm 对应于刚刚创建的 Realm,resource 对应于刚刚创建的客户端名称。 json { realm: UniHeart, auth-server-url: https://keycloak.jiwai.win/auth, ssl-required: external, resource: UniHeart-Client }

随后,添加 @jeff-tian/egg-keycloak 插件

shell npm install --save @jeff-tian/egg-keycloak

在 config/plugin.ts 文件中,增加如下配置:

typescript ... keycloak: { enable: true, package: @jeff-tian/egg-keycloak, }, ...

最后,在你想要保护的路由前,增加 Keycloak 中间件:

比如,在 /app/router/keycloak/index.ts 文件中,这样保护 /keycloak/login 路由(正如示例所做的)。关键就在于添加的 keycloak.protect() 中间件。 typescript import { Application } from egg

export default (app: Application) => { const { router } = app

const subRouter = router.namespace(/keycloak)

subRouter.get( keycloak.login, /login, app.keycloak.protect(), async ctx => { ctx.body = ctx.session[keycloak-token] }, ) }

完成!