单点登录 #
单点登录和开发语言,框架无关,这里以前端vue,后端springboot(java)进行说明,后面不再赘述。
JWT #
1. payload 具有如下信息: #
- iss: cmcim
- exp: 过期时间 Date类型
- clientType: 客户端类型 1 网页,2 PC客户端,3 移动端
- userId: 用户唯一标识,同集成系统的用户ID
- clientIp: 客户端IP地址
- deviceId: 客户端设备唯一标识
2. 加密算法采用HS256,密钥为UPush的AppSecret参照 (opens new window) #
3. Yo信生成jwt代码举例 #
JWT.create()
.setExpiresAt(date) // 默认为颁发时间5分钟后过期
.setIssuedAt(new Date()) // token颁发时间
.setIssuer("cmcim") // 颁发者固定为cmcim
.setPayload("clientType", 2)
.setPayload("userId", "7e3aea655b5489eac146434db452d290")
.setPayload("clientIp", "47.342.101.23")
.setPayload("deviceId", "6cdc0810a1b96e27")
.setSigner("HS256", upushSecret.getBytes(StandardCharsets.UTF_8)) // upushSecret为密钥
.sign();
4. 集成系统解析JWT举例 #
- 方式一,如果项目中已经使用了hutool,建议直接使用hutool中的JWT解析。如果没有可以在pom添加如下依赖:
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.11</version>
</dependency>
hutool解析:
JWT jwt = JWT.of(jwtToken);
// 密钥为UPush的AppSecret
boolean b = jwt.setKey(upushSecret.getBytes(StandardCharsets.UTF_8)).verify();
if (!b) {
log.error("jwt token invalid");
return;
}
// 取得userId,取得其他payload中的键值同理
String userId = (String) jwt.getPayloads().get("userId");
- 方式二,由于有的系统中并没有集成hutool,hutool是一个工具集其中有很多功能,没有必要为了解析jwt冗余引用依赖,可以引用专门解析jwt的库,如下:
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>
java-jwt解析:
// 密钥为UPush的AppSecret
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(upushSecret)).withIssuer("cmcim").build();
DecodedJWT decodedJWT;
try {
decodedJWT = jwtVerifier.verify(token);
} catch (TokenExpiredException e){
// ...
} catch (JWTVerificationException e) {
// ...
}
// 取得userId,取得其他payload中的键值同理
String userId = decodedJWT.getClaim("userId").asString()
鉴权 #
从Yo信跳转到集成系统页面如何鉴权?
- 前端
vue的项目中都会对路由的全局拦截用于判断登录状态做页面跳转,配置白名单无需鉴权即可访问的路径等等。Yo信在做跳转时会在Url携带参数yx_access_token。
router.beforeEach((to, from, next) => {
// yx_access_token不为空表示是从Yo信跳转过来的链接
if (to.query?.yx_access_token) {
}
})
前端拿到yx_access_token,有如下两种鉴权方式:
使用yx_access_token向后端做登录请求,这种方式对前/后端代码的侵入性最小推荐使用。发送登录请求前注意判断是否已经是登录状态,因为可能会多次且频繁的从Yo信跳转到集成系统画面,没必要每次跳转都执行登录请求。
前端直接使用yx_access_token对服务端请求,即前端直接把yx_access_toke当成系统本身的token去使用,由服务端判断是Yo信的token,还是系统本身的token,再进行鉴权。
- 后端
对应前端的方式1,后端添加一个使用yx_access_token登录的接口,由前端调用,返回和正常登录一样的内容即可。
对应前端的方式2,后端需要在校验系统token的位置添加对yx_access_token的校验,并构建和普通请求一样的请求上下文。无论是鉴权框架是Spring Securety,Shiro,或者自定义的拦截器都适用。