Keycloak现代化前端、移动端的接入说明

    接上文《Keycloak通用接入手册(以Java为例)》,前面所述的,都是针对于服务器端的接入说明。


    而现代化的前端技术,已经具备了很强大的native处理能力,很幸运,Keycloak已经提供JavaScript Adapter,它可以用于现代化的前端、移动端APP接入,GitHub上可以找到很多 VueJS、ReactJS、React Native的接入例子。

    下面以 VueJS APP为例,说明如何接入。

    主要参考的官方教程:javascript-adapter-reference

    首先教程中说明一点:One important thing to note about using client-side applications is that the client has to be a public client as there is no secure way to store client credentials in a client-side application.

    另外,据我所知,纯前端JS的权限控制,不应该作为安全控制的手段,后端APP还是需要做权限控制。

    比如,一个前后端分离的项目,前端 部署在端口为9999的服务器上,后端部署在 8080的服务器上,对Keycloak而言,这个两个不同的服务器,两个URL,对应于两个不同的client,所以,首先要在keycloak上新建两个client,基本信息如下:

服务器端的client:

{
  clientId: 'backend-app',
  root-url: 'http://localhost:8080/myapp',
  Access_Type: private,
  secret: d4589683-0ce7-4982-bcd3-c48a12572f79
}

前端的client:

{
  clientId: 'frontend-app',
  root-url: 'http://{ip}:9999',
  Access_Type: public
}

    注意,前端client是public没有密码的,因为前面说了,前端接入keycloak的目的,并不是为了做安全控制,而且前端存放密码没有安全意义。

    JS Adapter原理如下:

    keycloak.js会在页面嵌入一个 loginFrame,然后使用JS循环不断的检查token状态,如果没有token(没登录或者已登出),则会调用 kc.login方法使用 window.location.replace(ssoLoginUrl)的方式跳转到登录页面。同理退出登录的话,会调用kc.logout方法跳转。(详见 keycloak.js 源码)

    与VueJS APP接入的要点如下:

  • 在每个单独的页面,引入keycloak并做初始化(以便建立起loginFrame)。

  • 废掉之前的登录页面,以及登录拦截器(比如vue router里面的),因为它们已经没有作用了。

  • 关于用户信息,只能从keycloak.js获得用户名,更详细的信息,建议还是调后端api从数据库获取。

    以Vue UI框架为例,步骤如下

    1)第一步:npm install @dsb-norge/vue-keycloak-js --save

    2)第二步:在main.js里面添加:

import VueKeyCloak from '@dsb-norge/vue-keycloak-js'
 
// You can also pass in options. Check options reference below.
Vue.use(VueKeyCloak, options)

    配置好options即可,按照这个组件的教程:https://www.npmjs.com/package/@dsb-norge/vue-keycloak-js,把 new Vue(...) 放到onReady里面。如下所示:

Vue.use(VueKeyCloak, {
  config: {
    realm: 'demo',
    url: 'http://localhost:8180/auth/',
    clientId: 'fastvue',
    logoutRedirectUri: 'http://localhost:9527/#/login'
  },
  onReady: (keycloak) => {
    new Vue({
      el: '#app',
      router,
      store,
      i18n,
      render: h => h(App)
    })
  }
})

    3)第三步(非必须,视项目情况),修改原来的vue router

    比如我的是在permission.js里面,有个router.beforeEach((to, from, next),把它的登录判断逻辑改成

if (Vue.prototype.$keycloak.authenticated) {
    // 已登录
    // TODO 
}

    4)第四步,修改 退出登录的 逻辑。

    我是把原来退出方法的直接改成:

logout () {
    ...
    Vue.prototype.$keycloak.logoutFn()
}

    这样就OK了,它会调用 window.location 跳转登录页面去。


前、后端项目对接

    前面分别把 前端 和 后端 对接了Keycloak,那么怎么把前后端连接起来呢?

    思路如下:前端登录keycloak后,立即去后端登录一下,这样才能获得后端的session或token。

    第一步:

    1)如果用的是token登录,则写一个sso登录的接口,前端调用后,得到这个token,然后每次请求带上这个token就行了。

    Fast Vue框架为例,改动如下:

    在调用GetUserInfo之前,增加一个调用SSO Login API登录,登录后将token保存下来。


    2)如果用的是session(cookie)登录,则配置 AJAX的 withCredentials = true,这样每次请求都会带上登录的cookie信息。

    以Fast Admin 和 Fast Vue框架为例,改动如下:

    在前端ajax配置中,加上withCredentials = true

axios.create({
  baseURL: base_url,
  timeout: 5000, 
  withCredentials: true
})

    相应地,后端corsFilter(org.springframework.web.cors.CorsConfiguration)中也要加上:

config.setAllowCredentials(true);

    提醒,如果没有加 AllowedOrigin,也一定要加上,例如:

config.addAllowedOrigin("http://localhost:9527") // 前端的地址

    如果不懂Cors(跨域请求),参见这篇文章:http://newhtml.net/using-cors/ 

    第二步:

    在后端keycloak配置中,加入

keycloak.cors=true


总结:

    以Fast Vue框架为例,总共5个步骤:

  1. npm install @dsb-norge/vue-keycloak-js --save

  2. 在main.js里面配置vue-keycloak

  3. 修改router,把以前的登录判断逻辑,改成根据keycloak状态来判断

  4. 修改 退出登录的 逻辑,直接调用$keycloak.logoutFn()

  5. 废掉原来的登录页面和代码,改成调用后端的sso-login API,获得token后保存即可


下面再提供两个例子:

ReactJS例子:

https://github.com/dasniko/keycloak-reactjs-demo

AngularJS例子:

https://github.com/iuliazidaru/keycloak-spring-boot-rest-angular-demo


更多例子参见GitHub:

https://github.com/search?l=JavaScript&p=2&q=keycloak&type=Repositories

更多细节参见官方文档:

https://www.keycloak.org/docs/latest/securing_apps/index.html#_javascript_adapter


© 2009-2020 Zollty.com 版权所有。渝ICP备20008982号