Skip to content

接口签名

概述

接口签名是一项重要的安全机制,用于确保API和请求的真实性、数据的完整性以及防止重放攻击。

盘古签名前端组件使用

1、设置集团npm仓库

shell
# 修改npm私服地址(虚拟桌面使用)
npm config set registry http://nexus.hisense.com/repository/npm-public/
# 修改yarn私服地址(虚拟桌面使用)
yarn config set registry http://nexus.hisense.com/repository/npm-public/
# 修改pnpm私服地址(虚拟桌面使用)
pnpm config set registry http://nexus.hisense.com/repository/npm-public/

2、添加依赖

shell
# 使用pnpm
npm install pangea-web-signer
# 使用yarn
yarn add pangea-web-signer
# 使用pnpm
pnpm add pangea-web-signer

3、加/验签示例(仅支持Axios)

javaScript
import Axios from 'axios'
import {RequestSignObject, ResponseSignObject} from 'pangea-web-signer'

const axios = Axios.create({
    baseURL: 'http://localhost:8080',
    timeout: 5000,
    headers: {
        'Content-Type': 'application/json'
    }
})
// 设置签名密钥(盐值)
const salt = '1122334455'
const requestSignObject = new RequestSignObject({salt})
const responseSignObject = new ResponseSignObject({salt})
axios.interceptors.request.use(
    (config) => {
        console.log('请求拦截器', config)
        return requestSignObject.processSignature(config)
    },
    (error) => {
        return Promise.reject(error)
    }
)

axios.interceptors.response.use(
    (response) => {
        console.log('响应拦截器', response)
        responseSignObject.autoCheckSignature(response)
        return response.data
    },
    (error) => {
        return Promise.reject(error)
    }
)

export default axios

4、签名逻辑介绍(其他异构系统可自行实现)

a. 签名范围
  • 请求签名支持的Content-Type
    • text/plain
    • application/json
    • application/x-www-form-urlencoded
    • multipart/form-data
  • 响应签名支持的Content-Type
    • application/json
b. 签名算法支持
  • MD5 (默认算法)
  • SHA1
  • SHA256
  • SHA384
  • SHA512
c. 请求签名内容格式
  • text/plain或者application/json
# query需要按照参数名称正序排序
# header需要转小写字符后按照名称正序排序
method={METHOD/大写}&query.{name}={value}&header.{name}={value}&body={body}&salt={salt盐值}
  • application/x-www-form-urlencoded
# query和body需要按照参数名称正序排序(多个值按照值的字符正序排序)
# header需要转小写字符后按照名称正序排序
method={METHOD/大写}&query.{name}={value}&header.{name}={value}&body.{name}={value}&salt={salt盐值}
  • multipart/form-data
# query和body需要按照参数名称正序排序(多个值按照值的字符正序排序),如果body的某个参数是文件类型需要重新计算body参数的值具体的计算逻辑参考后面备注
# header需要转小写字符后按照名称正序排序
method={METHOD/大写}&query.{name}={value}&header.{name}={value}&body.{name}={value}&salt={salt盐值}
# 备注:body中的文件的值计算逻辑:
    分为两个文件签名模式:
      - 按文件元数据签名(默认):
        值格式:body.file=[name={fileName}&size={文件字节数}]
      - 按文件内容二次签名(性能差,安全性高):
        值格式:body.file={文件内容的MD5值}
d. 响应签名内容格式
  • application/json
# header需要转小写字符后按照名称正序排序
status={statusCode}&header.{name}={value}&content={content}&salt={salt盐值}

盘古签名后端依赖使用

1、设置集团nexus制品仓

xml
<!-- release库 -->
<repository>
    <id>hisense-nexus</id>
    <name>hisense-nexus</name>
    <url>http://nexus.hisense.com/repository/maven-public/</url>
</repository>

2、在业务模块的pom文件中添加依赖

html
<!--pangea公共工具包 -->
<dependency>
    <groupId>com.hisense.pangea</groupId>
    <artifactId>pangea-common-sign</artifactId>
    <version>${pangea.version}</version>
</dependency>

3、约定请求头和响应头中携带的信息

java
signature   // 签名
timestamp   // 时间戳
systemName  // 系统编码

4、加/验签示例

java
// 构建用于请求签名的对象
RequestSignObject requestSignObject = RequestSignObject.builder()
        .url("http://pangea-platform-stage.clouddev.hisense.com/api/path")
        .method("GET")
        .addHeader("systemName", "pangea")
        .addHeader("timestamp", "1751524636940")
        .query({name=zhangsan, age=11})
        .salt("eh3j4fjrifjv88")
        // .body(new FormBody(body, "multipart/form-data", "UTF-8"))
        .body(new SimpleByteBody(body, "application/json", "UTF-8"))   // 其中body为byte[]类型
        .build();
// 生成请求签名
String sign = JdkSigner.INSTANCE.sign(requestSignObject.buildSignContent(),
        HashAlgorithm.fromString("MD5"), SignFormat.HEX);
// 构建用于响应签名的对象
ResponseSignObject responseSignObject = ResponseSignObject.builder()
        .addHeader("systemName", "pangea")
        .addHeader("timestamp", "1751524636940")
        .salt("eh3j4fjrifjv88")        
        .statusCode("200")
        .content("\{\"code\":\"0\",\"message\":\"success\",\"data\":\"info\",\"alert\":\"1\"\}")
        .build();
// 生成响应签名
String sign = JdkSigner.INSTANCE.sign(responseSignObject.buildSignContent(),
        HashAlgorithm.fromString("SHA-256"), SignFormat.HEX);
// 验签
StringUtils.equals(headers.getFirst("signature"), sign)

5、使用盘古网关的接口签名功能须增加如下配置信息

  • 盘古中心化部署请联系盘古团队进行配置,独立部署请在nacos的yml文件中进行配置
yml
pangea:
    security:
        sign-timeout: 300000   # 请求过期时间 ms
        sign-switch: true   # 是否开启签名功能
        signature-apps:   # 系统签名配置列表
          - systemName: L0099   # 系统编码
            secretKey: ac17162bc09iu88   # 签名算法密钥
            algorithm: md5   # 签名算法
            sign-urls:   # 黑名单
              - /system/org/ **
            ignore-urls:   # 白名单(优先级高于黑名单,非必填)
              - /system/org/getOrgInfoAndUserInfoByName
            enableSignRequest: true   # 是否开启请求签名
            enableSignResponse: false   # 是否开启响应签名
            enableReqContentTypes: ["application/json","multipart/form-data"]   # 支持的请求内容类型
            enableResContentTypes: ["application/json"]   # 支持的响应内容类型