Open API(开放能力)
鸣谢
本功能最初由 Gitee@Caden-Yang 大佬提交 PR,感谢大佬的开源贡献。
后端 PR:https://gitee.com/continew/continew-admin/pulls/31
前端 PR:https://gitee.com/continew/continew-admin-ui/pulls/27
为了满足跨系统接口调用需求,自 3.4.0 版本起,我们新增了 [能力开放] 模块。在该模块中包含了 [应用管理] 功能,专门用于管理第三方系统应用的 AK/SK 信息。
此外,我们还借助 SaToken
的 api-sign
接口签名插件模块,实现了验签鉴权的能力。
下面将对 Open API 能力的使用进行简要介绍与说明。
新增应用
打开 [能力开放/应用管理] 菜单页面,点击 [新增],在弹出的对话框中依次填写应用名称、描述、过期时间等参数,确认无误后,点击 [确定] 即可创建一个新应用。
新增应用成功后,系统会自动生成 Access Key(AK)和 Secret Key(SK)信息。请务必复制并妥善保存这些信息,切勿泄露。若不慎泄露SK,可通过 [重置密钥] 功能进行重置,以确保应用安全。
重置密钥
若 Secret Key(SK)不慎泄露,可随时通过 [重置密钥] 功能来重新生成新的密钥,以确保应用安全。
认证鉴权
新增应用并配置完成后,您就可以凭借该应用的 AK/SK 来调用相应的开放能力了。下方将以调用查询角色列表接口为例,演示 Open API 认证鉴权参数构建过程。
前置:准备好如下信息。
// 应用 AK/SK
String accessKey = "应用AK";
String secretKey = "应用SK";
// API 地址
String apiUrl = "http://127.0.0.1:8000/system/role";
// 基础请求参数
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("description", "管理员");
1.应用的请求中必须加上 nonce
(随机字符串)参数,防止请求被无限重放。
// 随机字符串(唯一)
paramMap.put("nonce", RandomUtil.randomString(32));
2.应用的请求中必须加上 timestamp
(时间戳)参数,将请求的有效性限定在一个有限时间范围内(默认 15 分钟)。
// 时间戳
paramMap.put("timestamp", System.currentTimeMillis());
3.应用的请求中必须加上 accessKey
(AK)参数,用于标识应用身份。
// AK
paramMap.put("accessKey", accessKey);
4.应用的请求中必须加上 sign
(签名)参数,用于应用的身份验证和请求的防篡改验证。
// sign(签名)
paramMap.put("sign", sign);
sign
参数算法如下:
a.根据系统参数名称(除 sign)将所有请求系统参数按照自然顺序进行排序。
TreeMap<String, Object> buildSignParamMap = new TreeMap<>(paramMap);
b.拼接 key
(SK)参数。
注意:key
(SK)不在URL中传递,双方配置在自己系统中,用于计算 sign 值,增强安全性。
buildSignParamMap.put("key", secretKey);
c.将所有参数连接成一个字符串,例如:a=1&b=2&c=3。
String buildSignParamStr = HttpUtil.toParams(buildSignParamMap, null, false);
d.采用 MD5(32位小写)加密方式加密整个参数字符串。
String sign = SecureUtil.md5(buildSignParamStr);
5.拼接好如上鉴权参数后,即可顺利调用 API,完整代码如下:
// 应用 AK/SK
String accessKey = "应用AK";
String secretKey = "应用SK";
// API 地址
String apiUrl = "http://127.0.0.1:8000/system/role";
// 基础请求参数
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("description", "管理员");
// 构建鉴权参数
// 随机字符串
paramMap.put("nonce", RandomUtil.randomString(32));
// 时间戳
paramMap.put("timestamp", System.currentTimeMillis());
// AK
paramMap.put("accessKey", accessKey);
// 签名
// 将所有请求系统参数按照自然顺序进行排序
TreeMap<String, Object> buildSignParamMap = new TreeMap<>(paramMap);
// 拼接 key(SK)参数
buildSignParamMap.put("key", secretKey);
// 将所有参数连接成一个字符串,例如:a=18b=28c=3
String buildSignParamStr = HttpUtil.toParams(buildSignParamMap, null, false);
// 采用 MD5(32位小写)加密方式加密整个参数字符串
String sign = SecureUtil.md5(buildSignParamStr);
paramMap.put("sign", sign);
// 拼接完整的请求 URL
String fullUrl = apiUrl + "?" + HttpUtil.toParams(paramMap, null, false);
// 发送请求
String resp = HttpUtil.get(fullUrl);
log.info(resp);
参考资料
- SaToken API 接口参数签名:https://sa-token.cc/doc.html#/plugin/api-sign