一丶申请AppKey与AppSecret
与管理员联系获取appKey与appSecret,appKey是与数字人平台的客户渠道绑定的。
二丶 免登录服务端接入
2.1 AppKey+AppSecret 换 rabbitToken
服务调用数字人开放平台接口获取rabbitToken,接口文档地址:获取rabbitToken
rabbitToken 是调用所有数字人开放平台接口的令牌。
请妥善保管appKey和appSecret ,一般保存在服务端配置文件中。
2.2 携带rabbitToken 进行数字人平台登录并获取到重定向地址。
服务端提供联合登录接口给前端,接口内部逻辑:调用数字人开放平台接口(thirdId+thirdUrl)获取到重定向地址,并进行重定向。 接口文档地址:获取重定向URL
数字人开放平台内部逻辑:
- 判断是否绑定第三方用户Id(thirdId)
- 生成ticket 对于缓存了thirdId等
- 已绑定:生成数字人平台tz_token,并保存到ticket中
- 未绑定:后续要携带thirdId跳转到登录页面进行登录并绑定thirdId
注意:1. 接口请求头要携带tabbitToken
2. 如果是内嵌ifream形式 thirdUrl必须传入当前域名,数字人平台编辑器必须是同源。
2.3 前端调用服务端联合登录接口,进行免登录。
三丶Ifream内嵌页面处理
3.1 Nginx处理
要保证数字人平台与第三方是同一个域名,不然数字人编辑器内有浏览器同源策略限制。
需要第三方nginx代理一下数字人平台的域名。
配置参考如下:
server {
listen 80;
listen 443 ssl http2;
ssl_certificate "/opt/app/all_config/abug/cert.pem";
ssl_certificate_key "/opt/app/all_config/abug/key.pem";
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
server_name abug.jy520.fun;
# 这里是第三方主页
location / {
# 需要加两个允许跨域得头 不然无法进入数字人编辑器
add_header Cross-Origin-Opener-Policy same-origin;
add_header Cross-Origin-Embedder-Policy require-corp;
root /opt/app;
index test.html;
}
# 代理兔展后端
location /api/rabbitlab{
proxy_pass https://digitalman.h5no1.com;
}
# 代理兔展开放平台
location /open/platform{
proxy_pass https://digitalman.h5no1.com;
}
# 代理兔展前端页面
location /digitalman {
proxy_pass https://digitalman.h5no1.com;
}
}
3.2 前端Ifream参考
<iframe src="https://abug.jy520.fun/demo/unionLogin?thirdId=third_3" height="800px" width="100%" ></iframe>
其中 /demo/unionLogin 接口是第三方服务端提供 也就是2.2步中的。
四丶示例代码
4.1后端接入示例:
@Slf4j
@Component
public class RabbitOpenPlatformManager {
@Value("${openPlatform.host:https://test.digitalman.h5no1.com}")
private String host;
@Value("${openPlatform.appKey:069251338630322213976003}")
private String appKey;
@Value("${openPlatform.appSecret:924025c658bab641b4432b31921a37007d989e4be36f21c06dd477d2fb604d36}")
private String appSecret;
@Value("${openPlatform.thirdUrl:https://test.digitalman.h5no1.com}")
private String thirdUrl;
private static final String TOKEN_KEY = "openPlatform:token";
@Resource
private RedisTemplate<String, String> redisTemplate;
private final RestTemplate restTemplate = new RestTemplate();
/**
* 获得令牌
*
* @return {@link String}
*/
public String getToken() {
String rabbitToken = redisTemplate.opsForValue().get(TOKEN_KEY);
if (rabbitToken != null) {
return rabbitToken;
}
String url = "/open/platform/auth/getRabbitToken";
HashMap<String, String> map = new HashMap<>(2);
map.put("appKey", appKey);
map.put("appSecret", appSecret);
ParameterizedTypeReference<RabbitResponse<AppLoginResponse>> responseType = new ParameterizedTypeReference<RabbitResponse<AppLoginResponse>>() {
};
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/json; charset=UTF-8"));
HttpEntity<String> entity = new HttpEntity<>(JSONUtil.toJsonStr(map), headers);
ResponseEntity<RabbitResponse<AppLoginResponse>> exchange = restTemplate.exchange(host + url, HttpMethod.POST, entity, responseType);
RabbitResponse<AppLoginResponse> response = exchange.getBody();
log.info("response:{}", response);
if (response == null) {
throw new RuntimeException("响应异常");
}
if ("0".equals(response.getCode())) {
AppLoginResponse appLoginResponse = response.getData();
rabbitToken = appLoginResponse.getRabbitToken();
redisTemplate.opsForValue().set(TOKEN_KEY, rabbitToken, appLoginResponse.getExpireIn() / 2, TimeUnit.SECONDS);
return rabbitToken;
} else {
throw new RuntimeException(response.getErrorMsg());
}
}
/**
* 联合登录
*
* @param thirdId 第三方账户id
* @return {@link String}
*/
public String unionLogin(String thirdId) {
String url = "/open/platform/digital/third/getRedirectUrl";
HashMap<String, String> map = new HashMap<>(2);
map.put("thirdId", thirdId);
map.put("thirdUrl", thirdUrl);
ParameterizedTypeReference<RabbitResponse<RedirectUrlVo>> responseType = new ParameterizedTypeReference<RabbitResponse<RedirectUrlVo>>() {
};
HttpHeaders headers = new HttpHeaders();
headers.set("rabbitToken", getToken());
headers.setContentType(MediaType.parseMediaType("application/json; charset=UTF-8"));
HttpEntity<String> entity = new HttpEntity<>(JSONUtil.toJsonStr(map), headers);
ResponseEntity<RabbitResponse<RedirectUrlVo>> exchange = restTemplate.exchange(host + url, HttpMethod.POST, entity, responseType);
RabbitResponse<RedirectUrlVo> response = exchange.getBody();
if (response == null) {
throw new RuntimeException("响应异常");
}
if ("0".equals(response.getCode())) {
RedirectUrlVo data = response.getData();
return data.getRedirectUrl();
} else {
throw new RuntimeException(response.getErrorMsg());
}
}
@Data
static class RabbitResponse<T> {
private String code;
private String showMsg;
private String errorMsg;
private String requestId;
private T data;
}
@Data
static class AppLoginResponse {
/**
* 授权令牌
*/
private String rabbitToken;
/**
* 授权令牌 的有效期
*/
private Long expireIn;
}
@Data
static class RedirectUrlVo {
/**
* 重定向地址
*/
private String redirectUrl;
}
}
@RequestMapping("/")
@RestController
public class DemoController {
@Resource
private RabbitOpenPlatformManager rabbitOpenPlatformManager;
@GetMapping("/unionLogin")
public void unionLogin(String thirdId, HttpServletResponse response) throws IOException {
String redirectUrl = rabbitOpenPlatformManager.unionLogin(thirdId);
response.sendRedirect(redirectUrl);
}
}
4.2前端示例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<iframe src="https://xxx/demo/unionLogin?thirdId=third_3" height="800px" width="100%" id="myIframe"></iframe>
</body>
</html