Keycloak - docker 运行 前端集成

Keycloak - docker 运行 & 前端集成

这里的记录主要是跟我们的项目相关的一些本地运行/测试,云端用的 keycloak 版本不一样,不过本地我能找到的最简单的配置是这样的

docker 配置 & 运行 keycloak

keycloak 有官方(Red Hat Inc.)的镜像,官方文档里也提供了一些配置好的 Dockerfile,具体可以参考 https://www.keycloak.org/server/containers,最新的版本已经支持到了 v23。不过我这里用的是 JBoss 提供的镜像,上一次更新是两年前的事情,目前的版本是 v16.1.0,稍微有一点旧,优点在于不需要额外的配置和修改,只针对前端部分的测试会方便一些。

docker-compose.yaml 文件如下:

version: '3.8'
services:
  keycloak:
    container_name: keycloak
    image: jboss/keycloak:16.1.0
    volumes:
      - ./realm-config:/opt/jboss/keycloak/realm-config
      - ./keycloak-db:/opt/jboss/keycloak/standalone/data
    environment:
      - KEYCLOAK_USER=admin
      - KEYCLOAK_PASSWORD=pass
      - DB_VENDOR=h2
    ports:
      - 9090:8080

运行指令为 docker compose up,如下:

在这里插入图片描述

在这里插入图片描述

这个时候一个名为 keycloak 的 container 就启动了,这个时候访问 http://localhost:9090/auth/ 会看到以下界面:

在这里插入图片描述

admin 的用户名和密码可以直接在 docker 的环境配置里查看:

在这里插入图片描述

这里的配置是跟着 compose 文件来的,用户名是 admin,密码就是 pass

docker 文件简单解析

JBoss 已经接手了不少配置,所以 docker compose 文件比较简单,这里简单过一遍,不感兴趣的可以跳过到下一个 section,直接到前端集成部分。

  • version

    docker compose 文件的版本,目前标准配置要么是 3 要么是 3.8

  • services

    docker 要启动的 services/containers,这里只有一个 keycloak

    • keycloak

      这里启动的服务

      • container_name

        容器的名称

      • image

        这里的镜像名称是 JBoss 提供的 keycloak,在 docker 的镜像官网能找到,我这里顺带 tag 了一下版本

      • tag

        上面指定了版本,所以这个可以忽略

        如果 images 里面没有指定版本,tags 也不存在,那么就会自动拉 latest 版本

      • volumes

        这里相当于做一个数据的持久化,这样只要保存了对应的文件/文件夹,别的项目直接拉取,开启 docker 同样能够获取对应的 realms 和 client 信息,运行 docker compose up 后会自动创建对应的文件夹

        运行指令前,只有一个 compose 文件:

        在这里插入图片描述

        运行后自动生成对应的 realms 和 db:

        在这里插入图片描述

      • environment

        docker 的一些环境变量,上文提到了,用户名密码就是在这里设置的

      • ports

        这里是 docker 的 port mapping。默认 containers 的端口都是在 8080 上运行的,不过外部访问需要用其他的端口,可以理解成 <out_port>:<container_port>

        这也是为什么通过 http://localhost:9090/ 可以访问 keycloak

keycloak 极简配置

这里会生成一个 minimal 配置,大体就是需要创建 realm 和对应的 client,刚开始新登录的 realm 是空白的,只会有一个 master:

在这里插入图片描述

创建完的配置如下:

在这里插入图片描述

这里需要特别注意两个点:

  • web-origin,这个是 CORS 的设置,只有这个设置为 * 才能从其他的端口定向到 keycloak 所在的 port

  • valid redirect uri,这个需要设置前端部分的 port,如果没有设置的话会在登录页面抛出 invalid redirect uri

server 的信息,即 installation 如下:

{
  "realm": "OIDC-client",
  "auth-server-url": "http://localhost:9090/auth/",
  "ssl-required": "external",
  "resource": "vanilla",
  "public-client": true,
  "confidential-port": 0
}

前端集成

整个 OIDC client 的集成是一个很大的部分,我们也是在已经实现的 package 上新建了一个 wrapper,底层的实现使用的是 oidc-client-ts 这个 package,具体查看地址在 https://authts.github.io/oidc-client-ts/

keycloak 本身支持 Oauth 2.0, OpenID Connect(OIDC)和 SAML,所以这里 keycloak 和oidc-client-ts 的集成,一旦看懂这个 package 的代码,实现起来还是比较方便的。

这里依旧用 React 的代码实现,不过版本是 v17。React v18 会更新状态两次,从而导致 token 获取不一致无法顺利实现功能。

配置

配置这方面还是需要参考 Interface UserManagerSettings,网址:https://authts.github.io/oidc-client-ts/interfaces/UserManagerSettings.html

这里同样实现最低可需要的部分:

const config = {
  authority: 'http://localhost:9090/auth/realms/OIDC-client/',
  client_id: 'vanilla',
  redirect_uri: 'http://localhost:4200',
  silent_redirect_uri: 'http://localhost:4200',
  post_logout_redirect_uri: 'http://localhost:4200',
};
  • authority 是写死的值,这是 OIDC 接收的验证网址,即需要实现重定向的网址
  • client_id 就是 client

这部分参考 installation 即可

初始化

也就是实例化一个 UserManager:

// 建议写在配置文件里
const config = {
  authority: 'http://localhost:9090/auth/realms/OIDC-client/',
  client_id: 'vanilla',
  redirect_uri: 'http://localhost:4200',
  silent_redirect_uri: 'http://localhost:4200',
  post_logout_redirect_uri: 'http://localhost:4200',
};

const userManager = new UserManager(config);

登陆

功能如下:

const login = async () => {
  await userManager.signinRedirect();
};

userManager 会根据配置的信息进行重定向,如:

在这里插入图片描述

query param 会携带所有必需的信息,同样,对应的登录信息也会在返回的时候加到 query param 里:

在这里插入图片描述

更新

const refreshToken = async () => {
  await userManager.signinSilent();
};

这时候 userManager 就会背地调用对应的 token API,进行用户信息的更新,包括 access token,session time 之类的,这个在下面一个 section 会重新提到

这些根据对应的 idle 配置可以实现自动登出的功能

获取用户信息

这个部分相当于是最麻烦的,我写了一个 auth 函数去实现,如果没有用户信息的话就重定向到登录页面去:

const auth = async () => {
  const urlData = urlparse(window.location.href, true);
  if (urlData?.query?.state) {
    const storedState = await userManager.settings.stateStore?.get(
      urlData.query.state
    );

    if (storedState) {
      try {
        await userManager.signinRedirectCallback();
        logUser();
      } catch (e) {
        console.log(e);
      }
    } else {
      await login();
    }
  }
};

之前提到过了,在登录完成后 URL 会包含一些对应的 query param,如下:http://localhost:4200/?state=994a9e5d79f843ad822740007389b392&session_state=6dc0fd00-3229-49c3-b500-2f839f16538b&code=2acd9512-e8b1-4e8d-9e2b-362fc39912f5.6dc0fd00-3229-49c3-b500-2f839f16538b.541c1dbc-f6ab-4838-b9c1-7be9f09f5f50

这里主要需要的是 code,需要用这个值去调用 keycloak 的 token API 去获取对应的 token 信息,这也就是 userManager.signinRedirectCallback() 的用处,调用如下:

在这里插入图片描述

获取用户信息

token 正确获取之后,就可以通过调用 userManager 封装好的功能去获取用户信息了,如下:

const logUser = async () => {
  const user = await userManager.getUser();
  console.log(user);
};

在这里插入图片描述

其他

这里还是简化了很多的实现,UserManager 还是建议写成一个 singleton,这样可以在任意地方获取同一个 UserManager 的实例对象

这里是直接在 App.js 里面实现的功能,但是可以将实例化的 singleton 抽出来放到 Context 里面去,同样的 singleton 也可以在 axios instance 里面调用,实现自动注入 bearer token 到 header 里、自动更新 session 或是在 session 过期时自动登出等功能

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/348745.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

助力工业产品质检,基于YOLOv7【tiny/l/x】不同系列参数模型开发构建智能PCB电路板质检分析系统

AI助力工业质检智能生产制造已经有很多成功的实践应用了&#xff0c;在我们前面的系列博文中也有很多对应的实践&#xff0c;感兴趣的话可以自行移步阅读前面的博文即可&#xff1a; 《助力质量生产&#xff0c;基于目标检测模型MobileNetV2-YOLOv3-Lite实现PCB电路板缺陷检测…

python:socket基础操作(4)-《tcp客户端基础》

tcp就和udp不一样了&#xff0c;tcp是客户端和服务器端&#xff0c;如果想通过tcp发送数据&#xff0c;要先让tcp进行连接服务器端 tcp客户端 先让服务器端进行启动 import socketdef main():# 创建套接字tcp_client_socket socket.socket(socket.AF_INET,socket.SOCK_STREAM…

【原理图PCB专题】OrCAD Capture CIS关闭开始界面

17.4版本 在打开OrCAD Capture CIS时会发现打开Start Page页面&#xff0c;那么如何将他关闭再也不看这个界面呢&#xff1f; 在窗口中输入SetOptionBool EnableStartPage 0 回车 重启软件后就再也不会弹出Start Page页面 如果没有发现Command Window那么将菜单栏view->C…

Cesium绘制流动管线

目录 一、第一种方式 二、第二种方式 1.安装gsap 2.引入 一、第一种方式 使用viewer.clock Clock文档 viewer.clock文档 vec4 colorImage texture2D(image, vec2(fract(st.s - time), st.t));这里&#xff0c;因为使用的是高版本的cesium1.108,直接写texture2D会报错&am…

计数指针:shared_ptr (共享指针)与函数 笔记

推荐B站视频&#xff1a; 4.shared_ptr计数指针_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV18B4y187uL?p4&vd_sourcea934d7fc6f47698a29dac90a922ba5a3 5.shared_ptr与函数_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV18B4y187uL?p5&vd_sourcea…

JavaScript基础之输入输出与变量常量详解

输入和输出 输出和输入也可理解为人和计算机的交互&#xff0c;用户通过键盘、鼠标等向计算机输入信息&#xff0c;计算机处理后再展示结果给用户&#xff0c;这便是一次输入和输出的过程。 举例说明&#xff1a;如按键盘上的方向键&#xff0c;向上/下键可以滚动页面&#x…

C语言实现插入排序算法(附带源代码)

插入排序 插入排序&#xff08;英语&#xff1a;Insertion Sort&#xff09;是一种简单直观的排序算法。它的工作原理是通过构建有序序列&#xff0c;对于未排序数据&#xff0c;在已排序序列中从后向前扫描&#xff0c;找到相应位置并插入。插入排序在实现上&#xff0c;通常…

opencv012 滤波器04 中值滤波,双边滤波

中值滤波 取中位数&#xff0c;可以处理椒盐噪音 CV自带medianBlur函数dst cv2.medianBlur(src, ksize) 参数说明&#xff1a;1.src: 需要滤波的图片&#xff1b;2.ksize&#xff1a;核大小&#xff0c;必须是比1大的奇数【举个例子&#xff1a;3&#xff0c;5&#xff0c;7……

【RT-DETR有效改进】 | 主干篇 | RevColV1可逆列网络(特征解耦助力小目标检测)

前言 大家好&#xff0c;这里是RT-DETR有效涨点专栏。 本专栏的内容为根据ultralytics版本的RT-DETR进行改进&#xff0c;内容持续更新&#xff0c;每周更新文章数量3-10篇。 专栏以ResNet18、ResNet50为基础修改版本&#xff0c;同时修改内容也支持ResNet32、ResNet101和PP…

JDBC(Java DataBase Connectivity )

图片来源&#xff1a;动力节点老杜的JDBC视频讲解 JDBC&#xff08;Java DataBase Connectivity &#xff09; 一、JDBC 的本质二、开始前的准备工作三、关于 JDBC 中的事务四、JDBC 编程六步1.注册驱动2.获取连接3.获取数据库操作对象4.执行SQL语句5.处理结果查询集6.释放资源…

SpringBoot_基础

学习目标 基于SpringBoot框架的程序开发步骤 熟练使用SpringBoot配置信息修改服务器配置 基于SpringBoot的完成SSM整合项目开发 一、SpringBoot简介 1. 入门案例 问题导入 SpringMVC的HelloWord程序大家还记得吗&#xff1f; SpringBoot是由Pivotal团队提供的全新框架&…

docker指令存档

目录 Docker 1、概念 2、架构图 3、安装 4、Docker怎么工作的&#xff1f; 5、Docker常用命令 帮助命令 镜像命令 1、查看镜像 2、帮助命令 3、搜索镜像 4、拉取镜像 5、删除镜像 容器命令 1、启动 2、查看运行的容器 3、删除容器 4、启动&停止 其他命令…

苹果Find My市场需求火爆,伦茨科技ST17H6x芯片助力客户量产

苹果发布AirTag发布以来&#xff0c;大家都更加注重物品的防丢&#xff0c;苹果的 Find My 就可以查找 iPhone、Mac、AirPods、Apple Watch&#xff0c;如今的Find My已经不单单可以查找苹果的设备&#xff0c;随着第三方设备的加入&#xff0c;将丰富Find My Network的版图。产…

蓝桥杯备战——3.定时器前后台

1.STC15F2k61S2的定时器 阅读STC15系列的手册&#xff0c;我们可以看到跟STC89C52RC的定时器还是有不同之处的&#xff1a; 由上图可以看到我们可以通过AUXR寄存器直接设置定时器的1T/12T模式了 在定时器0/1模式上也可以设置为16位自动重装载。 另外需要注意IAP15F2K61S2只有…

python 学习之 re库的基本使用(正则匹配)上

目录 一、基本用法 二、函数介绍 1、match函数 2、search 函数 3、compile 函数 4、findall 和 finditer 函数 5、sub 函数和 subn 函数 6、split 函数 一、基本用法 首先我们需要引入 re 库 代码基本框架使用两行代码实现 测试代码&#xff1a; import reret re.m…

Linux管道学习(无名管道)

目录 1、概述 2、管道的创建 3、管道读写行为 3.1、管道读 在linux中管道有两种&#xff0c;一是无名管道&#xff08;匿名管道&#xff09;&#xff0c;第二种是有名管道&#xff1b;无名管道主要用于有血缘关系的父子进程间通信&#xff0c;有名管道则不受该限制&#xf…

描绘未知:数据缺乏场景的缺陷检测方案

了解更多方案内容&#xff0c;欢迎您访问官网&#xff1a;neuro-T | 友思特 机器视觉 光电检测&#xff1b;或联系销售经理&#xff1a;18124130753 导读&#xff1a; 深度学习模型帮助工业生产实现更加精确的缺陷检测&#xff0c;但其准确性可能受制于数据样本的数量。友思特…

Gradle学习笔记:Gradle的简介、下载与安装

文章目录 一、什么是Gradle二、为什么选择Gradle三、下载并安装Gradle四、Gradle的bin目录添加到环境变量五、测试Gradle是否安装正常 一、什么是Gradle Gradle是一个开源构建自动化工具&#xff0c;专为大型项目设计。它基于DSL&#xff08;领域特定语言&#xff09;编写&…

科大讯飞 再次引爆Ai

去年「科大讯飞版ChatGPT」星火大模型刚上线的时候&#xff0c;小编给大家推荐过一波&#xff0c;演示了其强大的功能&#xff0c;不少小伙伴都立马申请体验了一把&#xff0c;有小伙伴还私信我说功能非常强大&#xff0c;工作效率提高不少&#xff0c;支持国产大模型之类赞扬。…

idea 打包跳过测试

IDEA操作 点击蓝色的小球 手动命令 mvn clean package -Dmaven.test.skiptrue