与管理员联系获取appKey与appSecret,appKey是与数字人平台的客户渠道绑定的。
服务调用数字人开放平台接口获取rabbitToken,接口文档地址:获取rabbitToken
rabbitToken 是调用所有数字人开放平台接口的令牌。
请妥善保管appKey和appSecret ,一般保存在服务端配置文件中。
服务端提供联合登录接口给前端,接口内部逻辑:调用数字人开放平台接口(thirdId+thirdUrl)获取到重定向地址,并进行重定向。 接口文档地址:获取重定向URL
数字人开放平台内部逻辑:
注意:1. 接口请求头要携带tabbitToken
2. 如果是内嵌ifream形式 thirdUrl必须传入当前域名,数字人平台编辑器必须是同源。
要保证数字人平台与第三方是同一个域名,不然数字人编辑器内有浏览器同源策略限制。
需要第三方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; } } |
<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> |