取消
最近搜索
清空历史

API 授权与验证

快代理 API 会对每个访问请求进行身份验证,即每个请求都需要包含签名信息(signature参数)以验证请求者身份。 签名信息由API密钥生成,密钥包括 SecretId 和 SecretKey;每个订单都有对应的API密钥,API密钥相当于调用API的密码,一定要严格保密谨防泄露。

必须使用https调用接口

https加密传输可让API调用信息不被第三方监听和截获,更加安全。使用https只需保证API链接以https://开头。

签名验证方式

我们提供两种签名方式供您选择:

  1. 密钥令牌验证(默认)
  2. 数字签名验证

您可以根据自己的业务需要选择合适的签名验证方式。下面是对两种验证方式的详细说明。

密钥令牌验证

参数设置:sign_type=token

密钥令牌验证即提前调用get_secret_token接口获取密钥令牌(secret_token),将获取到的secret_token直接用作签名(signature)。
此验证方式非常简单,适合希望快速接入,不需要防篡改、防重放的开发者(需要防篡改、防重放请使用数字签名验证)。

关于令牌有效期

密钥令牌默认有效期为60分钟,您可以在会员中心-API设置里修改。

开发建议:

  • 您不必每次调用接口前都获取令牌,建议您本地保存获取到的secret_token,在合适的时候调用get_secret_token接口再次获取密钥令牌。
  • 您可以随时调用check_secret_token接口检查token有效性。

签名参数示例

signature=oxf0n0g59h7wcdyvz2uo68ph2s

使用示例:

以调用获取订单到期时间接口为例,当用户调用这一接口时,其请求参数可能如下:

参数 参数说明 参数值
secret_id 订单SecretId o1fjh1re9o28876h7c08
sign_type 鉴权方式 token
  1. 调用get_secret_token接口获取密钥令牌:

    secret_token: oxf0n0g59h7wcdyvz2uo68ph2s
    

  2. 直接将获取到的secret_token作为签名(signature)参数生成api链接:

    https://dev.kdlapi.com/api/getorderexpiretime?
    sign_type=token&secret_id=o1fjh1re9o28876h7c08&timestamp=1555080775&signature=oxf0n0g59h7wcdyvz2uo68ph2s
    

数字签名验证

参数设置:sign_type=hmacsha1

数字签名验证方式通过将调用参数+时间戳+随机数(可选)用SecretKey计算出签名进行验证,具有安全性好,防篡改、防重放的特点。

签名参数示例

sign_type=hmacsha1&timestamp=1555080775&signature=ooCUlI6XTxoPS5PG8gNMT37YVl4%3D

我们采用HMAC-SHA1方式进行数字签名,接下来对生成签名参数的步骤做一个详细介绍。

1. 生成签名串

以下是生成签名串的详细过程:

会员中心API密钥管理页得到订单的SecretId和SecretKey:

  • SecretId:o1fjh1re9o28876h7c08
  • SecretKey:jd1gzm6ant2u7pojhbtl0bam0xpzsm1c

注意: 上述取值只是示例,请根据您实际的 SecretIdSecretKey 进行后续操作!

以调用获取订单到期时间接口为例,当用户调用这一接口时,其请求参数可能如下:

参数 参数说明 参数值
secret_id 订单SecretId o1fjh1re9o28876h7c08
sign_type 鉴权方式 hmacsha1
timestamp 当前时间戳 1555064362

1.1 对参数排序

首先对所有请求参数按参数名的字典序( ASCII 码)升序排序。注意:
1)只按参数名进行排序,参数值保持对应即可,不参与比大小;
2)按 ASCII 码比大小,不是按字母表,也不是按数值。用户可以借助编程语言中的相关排序函数来实现这一功能,如 php 中的 ksort 函数。
上述示例参数的排序结果如下:

{
    "secret_id": "o1fjh1re9o28876h7c08",
    "sign_type": "hmacsha1",
    "timestamp": 1555064362,
}

使用其它程序设计语言开发时,可对上面示例中的参数进行排序,得到的结果一致即可。

1.2 拼接请求字符串

此步骤生成请求字符串。 将把上一步排序好的请求参数格式化成“参数名称”=“参数值”的形式,如对 SecretId 参数,其参数名称为 "secret_id" ,参数值为 "o1fjh1re9o28876h7c08" ,因此格式化后就为 secret_id=o1fjh1re9o28876h7c08 。

注意: “参数值”为原始值而非url编码后的值。

然后将格式化后的各个参数用"&"拼接在一起,最终生成的请求字符串为:

secret_id=o1fjh1re9o28876h7c08&sign_type=hmacsha1&timestamp=1555069980

1.3 拼接签名原文字符串

此步骤生成签名原文字符串。 签名原文字符串由以下几个参数构成:

  1. 请求方法: 支持 POST 和 GET 方式,这里使用 GET 请求,注意方法为全大写。
  2. 请求路径: 例如获取订单到期时间的请求路径为:/api/getorderexpiretime。实际的请求路径根据接口的不同而不同,详见各接口描述。
  3. 请求字符串: 即上一步生成的请求字符串。

签名原文串的拼接规则为: 请求方法 + 请求路径 + ? + 请求字符串

示例的拼接结果为:

GET/api/getorderexpiretime?secret_id=o1fjh1re9o28876h7c08&sign_type=hmacsha1&timestamp=1555069980

1.4 生成签名串

此步骤生成签名串。首先使用 HMAC-SHA1 算法对上一步中获得的签名原文字符串进行签名,然后将生成的签名串使用 Base64 进行编码,即可获得最终的签名串。

具体代码如下,以 PHP 语言为例:

<?php
$secretKey = 'jd1gzm6ant2u7pojhbtl0bam0xpzsm1c';
$rawStr = 'GET/api/getorderexpiretime?secret_id=o1fjh1re9o28876h7c08&sign_type=hmacsha1&timestamp=1555069980';
$signStr = base64_encode(hash_hmac('sha1', $rawStr, $secretKey, true));
echo $signStr;

最终得到的签名串为:

ooCUlI6XTxoPS5PG8gNMT37YVl4=

使用其它程序设计语言开发时,可用上面示例中的原文进行签名验证,得到的签名串与例子中的一致即可。

1.5 签名串编码

生成的签名串并不能直接作为请求参数,需要对其进行 URL 编码。

如上一步生成的签名串为ooCUlI6XTxoPS5PG8gNMT37YVl4=,最终得到的签名串请求参数(signature)为 ooCUlI6XTxoPS5PG8gNMT37YVl4%3D, 它将用于生成最终的api链接。

提示

  1. 如果用户的请求方法是 GET,或者请求方法为 POST 同时 Content-Type 为 application/x-www-form-urlencoded,则发送请求时所有请求参数的值均需要做 URL 编码,参数键和=符号不需要编码。非 ASCII 字符在 URL 编码前需要先以 UTF-8 进行编码。

  2. 有些编程语言的 http 库会自动为所有参数进行 urlencode,在这种情况下,就不需要对签名串进行 URL 编码了,否则两次 URL 编码会导致签名失败。

  3. 其他参数值也需要进行编码,编码采用 RFC 3986。使用 %XY 对特殊字符例如汉字进行百分比编码,其中“X”和“Y”为十六进制字符(0-9 和大写字母 A-F),使用小写将引发错误。

1.6 生成api链接示例

以getorderexpiretime接口为例,最终输出api链接为:

https://dev.kdlapi.com/api/getorderexpiretime?
sign_type=hmacsha1&secret_id=o1fjh1re9o28876h7c08&timestamp=1555080775&signature=ooCUlI6XTxoPS5PG8gNMT37YVl4%3D

温馨提示

由于示例中的密钥是虚构的,时间戳也不是系统当前时间。为了得到一个可以正常返回的 url ,需要修改示例中的 secret_id 和 secret_key 为真实订单的密钥信息,并使用系统当前时间戳作为 timestamp 。

在实际调用 API 时,推荐使用配套的SDK,SDK 封装了签名的过程,开发时只关注产品提供的具体接口即可。详细信息参见 SDK中心

2. 代码示例

提示

  1. 在下面的示例中,不同编程语言,甚至同一语言每次执行得到的 url 可能都有所不同,表现为参数的顺序不同,但这并不影响正确性。只要所有参数都在,且签名计算正确即可。
  2. 其他语言示例请参考 代码样例-数字签名 (sdk_hmacsha1)
Python示例
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import json
import time
import base64
import hashlib
import hmac

import requests

class Auth:
    """用于保存用户secret_id、secret_key,以及计算签名的对象。"""
    def __init__(self, secret_id, secret_key):
        self.secret_id = secret_id
        self.secret_key = secret_key

    @classmethod
    def get_string_to_sign(cls, method, endpoint, params):
        """ 生成签名原文字符串 """
        s = method + endpoint.split('.com')[1] + '?'
        query_str = '&'.join("%s=%s" % (k, params[k]) for k in sorted(params))
        return s + query_str

    def sign_str(self, raw_str, method=hashlib.sha1):
        """ 生成签名串 """
        try:
            hmac_str = hmac.new(self.secret_key.encode('utf8'), raw_str.encode('utf8'), method).digest()
        except UnicodeDecodeError as e:
            hmac_str = hmac.new(self.secret_key.encode('utf8'), raw_str, method).digest()
        return base64.b64encode(hmac_str)

def _get_base_res(method, endpoint, params):
    """处理基础请求,
       若响应为json格式则返回请求结果dict
       否则直接返回原格式
    """
    try:
        r = None
        if method == "GET":
            r = requests.get("https://" + endpoint, params=params)
        elif method == "POST":
            r = requests.post("https://" + endpoint, data=params)
        if r.status_code != 200:
            return 'HTTP Status Code: %s' % r.status_code
        try:
            return json.loads(r.content.decode('utf8'))
        except ValueError as e:  # 返回结果不是json格式, 直接返回
            return r.content.decode('utf8')
    except Exception as e:
        print(str(e))


if __name__ == '__main__':
    secret_id = 'o1fjh1re9o28876h7c08'
    secret_key = 'jd1gzm6ant2u7pojhbtl0bam0xpzsm1c'
    method = 'GET'  # 请求方式
    endpoint = 'dev.kdlapi.com/api/getorderexpiretime'
    # 除signature外的所有参数都放入params
    params = { 
        'secret_id': secret_id,
        'sign_type': 'hmacsha1',
        'timestamp': int(time.time()),
    }

    auth = Auth(secret_id, secret_key)
    raw_str = auth.get_string_to_sign(method, endpoint, params)
    params['signature'] = auth.sign_str(raw_str)
    res = _get_base_res(method, endpoint, params)
    print(res)

3. SDK下载

通过sdk封装了签名计算过程,让您免去了这部分的编程工作,配置好apikey即可调用。

联系我们