通过Python和SUDS访问Kashoo API。认证令牌中的时间格式问题

3 投票
1 回答
731 浏览
提问于 2025-04-16 21:12

我正在尝试使用Python中的SUDS访问这个API https://www.kashoo.com/api-docs

我使用的Python代码如下:

>>> from suds.client import Client
>>> client = Client('https://www.kashoo.com/api/v1?wsdl')
>>> token = client.service.doLogin('username', 'password', 'www.kashoo.com', 'en_US', 3000000)

authToken的创建没有问题:

>>> print token
(authToken){
_authenticationCode = "crxQRveuVaDb6swKCJaQKKPiYaY="
_expiryDate = 2011-07-10 12:49:28.000702
_locale = "en_US"
_myUserId = 531772668
_site = "www.kashoo.com"

问题出现在我尝试对这个token进行编码,并生成一个编码后的认证字符串时。

>>>encodedtoken = client.service.encodeAuthToken(token)
Traceback (most recent call last):
 File "<console>", line 0, in <module>
 File "C:\Python27\lib\suds\client.py", line 542, in __call__
   return client.invoke(args, kwargs)
 File "C:\Python27\lib\suds\client.py", line 602, in invoke
   result = self.send(soapenv)
 File "C:\Python27\lib\suds\client.py", line 649, in send
   result = self.failed(binding, e)
 File "C:\Python27\lib\suds\client.py", line 702, in failed
    r, p = binding.get_fault(reply)
 File "C:\Python27\lib\suds\bindings\binding.py", line 265, in get_fault
    raise WebFault(p, faultroot)
 WebFault: Server raised fault: 'Token authentication code is incorrect'

问题似乎出在token中的时间格式上。调用doLogin函数后收到的信封内容如下:

 <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
 <soap:Body>                  
 <ns2:doLoginResponse xmlns:ns2="https://www.kashoo.com/api/">
      <token authenticationCode="0WM1DgdaAFrJ7Yz4Up2UWnbVsZk=" expiryDate="2011-07-11T03:33:24.046-07:00" locale="en_US" myUserId="531772668" site="www.kashoo.com"/>
 </ns2:doLoginResponse>
 </soap:Body>
 </soap:Envelope>

如果我使用像soapUI这样的工具将那个token传递给Kashoo API,它可以正常工作。然而,当我在Python中使用SUDS调用encodeAuthToken函数时,生成的SOAP信封如下:

<SOAP-ENV:Envelope xmlns:ns0="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="https://www.kashoo.com/api/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <ns0:Body>
      <ns1:encodeAuthToken>
         <token authenticationCode="0WM1DgdaAFrJ7Yz4Up2UWnbVsZk=" expiryDate="2011-07-11T11:33:24.000046+01:00" locale="en_US" myUserId="531772668" site="www.kashoo.com"/>
      </ns1:encodeAuthToken>
   </ns0:Body>
</SOAP-ENV:Envelope>

注意expiryDate属性的时间格式是如何变化的:

 <token authenticationCode="0WM1DgdaAFrJ7Yz4Up2UWnbVsZk=" expiryDate="2011-07-11T03:33:24.046-07:00" locale="en_US" myUserId="531772668" site="www.kashoo.com"/>
 <token authenticationCode="0WM1DgdaAFrJ7Yz4Up2UWnbVsZk=" expiryDate="2011-07-11T11:33:24.000046+01:00" locale="en_US" myUserId="531772668" site="www.kashoo.com"/>

在收到的token中,时间是以毫秒为单位的,而在传递的token中,时间是以微秒为单位的。

问题解决了。

在SUDS库中,我修改了suds.sax.date模块的第218行,将

            return dt.time(hour, minute, second, ms)

替换为

            return dt.time(hour, minute, second, 1000 * ms)

现在当我获取token时,时间属性被正确解析并传递。

>>> print token1
    (authToken){
        _locale = "en_US"
        _authenticationCode = "JQyior8Qprg3+3wuZo8B5JnN3c8="
        _myUserId = 531772668
        _site = "www.kashoo.com"
        _expiryDate = 2011-07-11 18:36:38.136000
       }
>>> token2 = client.service.encodeAuthToken(token1)
>>> print token2
    6454e3af-b09d-4484-90b3-ea2632ab9fe4

我刚开始学习编程,这个解决方案远非完美,但似乎有效。

感谢@dobesv的反馈和指导。

1 个回答

0

如果你能记录下通过网络发送的HTTP请求和响应的日志,这可能会帮助你找到问题所在。看起来你已经在朝着正确的方向努力了。

其他的调用有没有成功?比如说service.getMyBusinesses(token)这个调用呢?

另外,你也可以考虑使用REST API,而不是SOAP,看看这样是否能解决问题。

撰写回答