用有云开放平台自建应用接入demo

前言

最近在做一个银行的对接项目,
需要从银行端拉取流水信息的结构化数据和回单。
其中数据抓取涉及到了签名及token生成的步骤。

我查了下token生成的接口,发现是参照了用友云开放平台的自建应用接入demoGitHub - yonyoucloud-open/corp-demo: 开放平台自建应用接入 demo里的逻辑。
但是demo里给出的代码部分,只有java代码,而且部分关键的引用库原始代码也没有提供出来。

为了做下api的调用测试,而且我只会码python,又没有demo代码样例,所以只能自己动手了。

整体逻辑

获取 token的方法

请求参数:

字段 类型 说明
appKey string 应用 appKey
timestamp number long unix timestamp, 毫秒时间戳
signature string 校验签名,HmacSHA256,加签方式看下文

其中,签名字段 signature 计算使用 HmacSHA256,具体计算方式如下:

1
URLEncode( Base64( HmacSHA256( parameterMap ) ) )

其中,parameterMap 按照参数名称排序,参数名称与参数值依次拼接(signature字段除外),形成待计算签名的字符串。之后对 parameterMap
使用 HmacSHA256 计算签名,Hmackey 为自建应用的 appSecret 。计算出的二进制签名先进行 base64,之后进行 urlEncode
即得到 signatrue 字段的值。

python代码部分

  1. appkey:
    首先是接口方提供的。
    我呢把一些接口方提供的参数,都写在了一个外部的conf文件里,然后py程序去读取。conf文件里是定义了一个json字典。

    1
    2
    3
    4
    5
    import json

    with open("conf.cfg", "r") as f:
    conn_string = json.load(f)["elements"]
    appKey = conn_string["appkey"]
  2. timestamp:
    用java中System.currentTimeMillis()方法返回的值,开发语言不同,需改为和java一样的时间戳。
    这个在python里可以通过round函数直接转换生成。

    1
    2
    3
    import time

    timestamp = str(round(time.time() * 1000))
  3. signature:
    parameterMap需要将key和timestamp的参数及值进行拼接。
    例如:key为k1234,timestamp转换出来的值为1657184970319。则拼接后parameterMap为:keyk1234timestamp1657184970319
    进行加签及编码。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    import hmac, base64
    from hashlib import sha256
    import urllib.parse
    import hashlib

    parameterMap = 'appKey{}timestamp{}'.format(appKey, timestamp)

    appsecret = conn_string["appSecret"].encode('utf-8')
    parameterMap = parameterMap.encode('utf-8')
    signature = base64.b64encode(hmac.new(appsecret, parameterMap, digestmod=hashlib.sha256).digest())
    signature = urllib.parse.quote_plus(signature)
  4. 接口调用获取token:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    import requests

    url = ("****/getToken?"
    "appKey={}"
    "&timestamp={}"
    "&signature={}".format(appKey, timestamp, signature))
    response = requests.get(url)

    #获取的token就在这里。
    token_get = json.loads(response.text)["data"]["access_token"]

总结

逻辑捋好了的话,其实代码部分很简单。
只是加签规则因为用到了好多没有过的方法,所以还是研究一下子的。
记录一下,后面如果有其他的项目能参考到,那就算没白研究了。