公共请求地址和处理

<p><span style="font-size:16px"><strong>&nbsp;请求地址</strong></span></p> <table border="1" cellpadding="0" cellspacing="0" style="width:811px"> <tbody> <tr> <td style="background-color:#ededed; vertical-align:top; width:155px"> <p><strong>环境</strong></p> </td> <td style="background-color:#ededed; vertical-align:top; width:288px"> <p><strong>HTTP</strong></p> </td> <td style="background-color:#ededed; vertical-align:top; width:360px"> <p><strong>HTTPS</strong></p> </td> </tr> <tr> <td style="vertical-align:top; width:155px"> <p>生产</p> </td> <td style="vertical-align:top; width:288px"> <p>http://apigw.yun.pingan.com/rest/{type}</p> </td> <td style="vertical-align:top; width:360px"> <p>https://apigw.yun.pingan.com/rest/{type}</p> </td> </tr> <tr> <td style="vertical-align:top; width:155px"> <p>测试</p> </td> <td style="vertical-align:top; width:288px"> <p>http://10.25.82.49:8080/rest/{type}</p> </td> <td style="vertical-align:top; width:360px"> <p>https://10.25.82.49:8080/rest/{type}</p> </td> </tr> </tbody> </table> <p>&nbsp;</p> <p><span style="font-size:16px"><strong>公共请求参数(系统级Header)</strong></span></p> <table border="1" cellpadding="0" cellspacing="0" style="width:809px"> <tbody> <tr> <td style="background-color:#ededed; vertical-align:top; width:188px"> <p><strong>名称</strong></p> </td> <td style="background-color:#ededed; vertical-align:top; width:92px"> <p><strong>类型</strong></p> </td> <td style="background-color:#ededed; vertical-align:top; width:88px"> <p><strong>默认</strong></p> </td> <td style="background-color:#ededed; vertical-align:top; width:127px"> <p><strong>示例值</strong></p> </td> <td style="background-color:#ededed; vertical-align:top; width:305px"> <p><strong>说明</strong></p> </td> </tr> <tr> <td style="vertical-align:top; width:188px"> <p>PA-AG-AppId</p> </td> <td style="vertical-align:top; width:92px"> <p>String</p> </td> <td style="vertical-align:top; width:88px"> <p>必填</p> </td> <td style="vertical-align:top; width:127px"> <p>123</p> </td> <td style="vertical-align:top; width:305px"> <p>应用编号,在消息云平台申请的应用编号</p> </td> </tr> <tr> <td style="vertical-align:top; width:188px"> <p>PA-AG-Signature</p> </td> <td style="vertical-align:top; width:92px"> <p>String</p> </td> <td style="vertical-align:top; width:88px"> <p>必填</p> </td> <td style="vertical-align:top; width:127px"> <p>20170315120000</p> </td> <td style="vertical-align:top; width:305px"> <p>签名字符串</p> </td> </tr> <tr> <td style="vertical-align:top; width:188px"> <p>PA-AG-Timestamp</p> </td> <td style="vertical-align:top; width:92px"> <p>String</p> </td> <td style="vertical-align:top; width:88px"> <p>必填</p> </td> <td style="vertical-align:top; width:127px"> <p>&nbsp;</p> </td> <td style="vertical-align:top; width:305px"> <p>API 调用者传递时间戳,值为当前时间的毫秒数,也就是从1970年1月1日起至今的时间转换为毫秒,时间戳有效时间为15分钟。</p> </td> </tr> <tr> <td style="vertical-align:top; width:188px"> <p>PA-AG-GroupId</p> </td> <td style="vertical-align:top; width:92px"> <p>String</p> </td> <td style="vertical-align:top; width:88px"> <p>必选</p> </td> <td style="vertical-align:top; width:127px"> <p>123456</p> </td> <td style="vertical-align:top; width:305px"> <p>分组ID,可通过API网关控制-分组管理-分组详情获取</p> </td> </tr> <tr> <td style="vertical-align:top; width:188px"> <p>PA-AG-RequestId</p> </td> <td style="vertical-align:top; width:92px"> <p>String</p> </td> <td style="vertical-align:top; width:88px"> <p>可选</p> </td> <td style="vertical-align:top; width:127px"> <p>1.0</p> </td> <td style="vertical-align:top; width:305px"> <p>API 调用者生成的请求&nbsp;ID,结合时间戳防重放,若不存在则网关会生成格式为&nbsp;AG-%{UUID}的请求&nbsp;ID&nbsp;,其中&nbsp;%{UUID}&nbsp;为网关生成的&nbsp;UUID,当出现请求异常时返回给调用者,方便排查异常。</p> </td> </tr> <tr> <td style="vertical-align:top; width:188px"> <p>PA-AG-Signature-Headers</p> </td> <td style="vertical-align:top; width:92px"> <p>String</p> </td> <td style="vertical-align:top; width:88px"> <p>可选</p> </td> <td style="vertical-align:top; width:127px"> <p>&nbsp;</p> </td> <td style="vertical-align:top; width:305px"> <p>参与校验的其他请求头,格式为&nbsp;header1,header2...headerN&nbsp;,&nbsp;header之间可以存在空格,分隔符为英文逗号&nbsp;,&nbsp;。</p> </td> </tr> <tr> <td style="vertical-align:top; width:188px"> <p>PA-AG-Env</p> </td> <td style="vertical-align:top; width:92px"> <p>String</p> </td> <td style="vertical-align:top; width:88px"> <p>可选</p> </td> <td style="vertical-align:top; width:127px"> <p>&nbsp;</p> </td> <td style="vertical-align:top; width:305px"> <p>请求API的发布环境名称。如果不传该值,则默认请求release环境的API</p> </td> </tr> </tbody> </table> <p><strong>&nbsp;</strong></p> <p><span style="font-size:16px"><strong>公共响应参数</strong></span></p> <table border="1" cellpadding="0" cellspacing="0" style="width:811px"> <tbody> <tr> <td style="background-color:#ededed; vertical-align:top; width:139px"> <p><strong>名称</strong></p> </td> <td style="background-color:#ededed; vertical-align:top; width:141px"> <p><strong>类型</strong></p> </td> <td style="background-color:#ededed; vertical-align:top; width:213px"> <p><strong>示例</strong></p> </td> <td style="background-color:#ededed; vertical-align:top; width:308px"> <p><strong>说明</strong></p> </td> </tr> <tr> <td style="vertical-align:top; width:139px"> <p>code</p> </td> <td style="vertical-align:top; width:141px"> <p>String</p> </td> <td style="vertical-align:top; width:213px"> <p>000000</p> </td> <td style="vertical-align:top; width:308px"> <p>返回码,如果返回非000000,则表明请求异常,用户可根据需求进行异常处理。</p> </td> </tr> <tr> <td style="vertical-align:top; width:139px"> <p>msg</p> </td> <td style="vertical-align:top; width:141px"> <p>String</p> </td> <td style="vertical-align:top; width:213px"> <p>成功</p> </td> <td style="vertical-align:top; width:308px"> <p>返回信息描述</p> </td> </tr> <tr> <td style="vertical-align:top; width:139px"> <p>appid</p> </td> <td style="vertical-align:top; width:141px"> <p>String</p> </td> <td style="vertical-align:top; width:213px"> <p>&nbsp;</p> </td> <td style="vertical-align:top; width:308px"> <p>应用编号</p> </td> </tr> <tr> <td style="vertical-align:top; width:139px"> <p>extend</p> </td> <td style="vertical-align:top; width:141px"> <p>String</p> </td> <td style="vertical-align:top; width:213px"> <p>&nbsp;</p> </td> <td style="vertical-align:top; width:308px"> <p>公共回传参数</p> </td> </tr> <tr> <td style="vertical-align:top; width:139px"> <p>expiretime</p> </td> <td style="vertical-align:top; width:141px"> <p>String</p> </td> <td style="vertical-align:top; width:213px"> <p>20170315123000</p> </td> <td style="vertical-align:top; width:308px"> <p>签名过期时间</p> <p>yyyyMMddHHmmss</p> </td> </tr> <tr> <td style="vertical-align:top; width:139px"> <p>token</p> </td> <td style="vertical-align:top; width:141px"> <p>String</p> </td> <td style="vertical-align:top; width:213px"> <p>&nbsp;</p> </td> <td style="vertical-align:top; width:308px"> <p>新的签名</p> </td> </tr> </tbody> </table> <p><strong>&nbsp;</strong></p> <ul> <li><strong>请求签名计算说明</strong></li> </ul> <p>请求签名,是基于请求内容计算的数字签名,用于API识别用户身份。客户端调用API时,需要在请求中添加计算的签名(PA-AG-Signature)。</p> <ul> <li><strong>签名计算流程</strong></li> </ul> <table border="1" cellpadding="1" cellspacing="1" style="width:812px"> <tbody> <tr> <td style="background-color:#ededed; width:804px"> <p>准备App &gt; 构造待签名字符串stringToSign &gt; 使用Secret计算签名 &gt; 传递签名</p> <p>##### 1.准备APP</p> <p>App,调用API的身份标识,可以到平安云<a href="https://yun.pingan.com/console/apiGateway/app">API网关控制台</a>申请</p> <p>##### 2.构造待签名字符串stringToSign</p> <p>String strToSign = HttpMethod + URI + Headers + ContentDigest</p> <p>#### HttpMethod</p> <p>请求方法,格式为大写,如`GET`,`POST`</p> <p>#### URI</p> <p>`URI` 指 `Path + Query`,组织方法:对 `Query` 参数按照字典对 `Key` **按照字典排序**后按照如下方法拼接,如果 `Query` 参数为空,则 `URL = Path`,不需要添加 `?`,如果某个参数的 `Value` 为空只保留 `Key` 参与签名,等号`=`不需要再加入签名。</p> <p>```java</p> <p>String url = Path +&quot;?&quot; +Key1 + &quot;=&quot; + Value1 +&quot;&amp;&quot; + Key2 + &quot;=&quot; + Value2 +...&quot;&amp;&quot; + KeyN + &quot;=&quot; + ValueN</p> <p>`Query` 的 `Key` 和 `Value` 是还未进行 `Encoding` 的原数据,关于 `Encoding` 详见[RFC3986](https://tools.ietf.org/html/rfc3986#section-2.1)。参数的 `Value` 可能有多个,多个的时候根据 `Value` 的**字典顺序**进行排序参与签名计算。</p> <p>示例:`String url = &quot;/some/path.html?key1=value1&amp;key2=value2&amp;key2=value3&amp;key3&quot;`</p> <p>#### Headers</p> <p>Headers 是指参与签名计算的请求头的 `Key`、`Value` 拼接的字符串。参与签名计算的请求头包括 `PA-AG-Timestamp` 以及 `PA-AG-Signature-Headers` 中填写的需要校验的其他请求头。请求头大小写**不敏感**。</p> <p>##### Headers拼接方式</p> <p>先对参与签名计算的 `Header` 的 `Key` **按照字典排序**后使用如下方式拼接,如果某个 `Header` 的 `Value` 为空,则使用 `HeaderKey.toLowercase() + &quot;:&quot;` 参与签名,需要保留 `Key` 和英文冒号 `:`,并且 `Key` 和 `Value` 左右两边不能有空白字符。`Header`的 `Value` 可能有多个,多个的时候根据 `Value` 的**字典顺序**进行排序参与签名计算。</p> <p>String headers =</p> <p>HeaderKey1.toLowercase() + &quot;:&quot; + HeaderValue1.toLowercase() + &quot;\n&quot;\+</p> <p>HeaderKey2.toLowercase() + &quot;:&quot; + HeaderValue2.toLowercase() + &quot;\n&quot;\+</p> <p>...</p> <p>HeaderKeyN.toLowercase() + &quot;:&quot; + HeaderValueN.toLowercase() + &quot;\n&quot;</p> <p>#### Content-Digest</p> <p>`Content-Digest` 是指 Body 的 `MD5` 值,只有当请求Body存在时才需要进行计算,计算方式为:</p> <p>String contentDigest = Base64.encodeBase64(MD5(requestBody.getbytes(&quot;UTF-8&quot;)));</p> <p>### 计算签名</p> <p>Mac hmacSha256 = Mac.getInstance(&quot;HmacSHA256&quot;);</p> <p>byte[] keyBytes = secret.getBytes(&quot;UTF-8&quot;);</p> <p>hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, &quot;HmacSHA256&quot;));</p> <p>String sign = new String(Base64.encodeBase64(hmacSha256.doFinal(strToSign.getBytes(&quot;UTF-8&quot;)),&quot;UTF-8&quot;));</p> <p>`secret `为App的密钥。*注:签名算法为创建api时选择的签名算法类型,目前支持 **HmacSHA1** 和 **HmacSHA256** 两种。</p> <p>**3.传递签名**</p> <p>将计算的签名结果放到 Request 的 Header 中,Key为PA-AG-Signature</p> </td> </tr> </tbody> </table> <p><strong>说明:获取更多信息,可参考<a href="https://yun.pingan.com/ssr/help/middleware/APIGateway/DevelopmentFile">API网关</a>。</strong></p>
以上内容是否解决了您的问题?
请补全提交信息!
咨询·建议

电话咨询

400-151-8800

邮件咨询

cloud@pingan.com

在线客服

工单支持

解决云产品相关技术问题