在Python 3.3中使用requests和requests-oauthlib进行API调用认证

2 投票
1 回答
1749 浏览
提问于 2025-04-17 22:59

我正在尝试用Python 3写一个自己的Cryptsy API封装,使用的是requests和requests-oauthlib这两个库。我对API调用和Python都很陌生。目前,我遇到了这个错误:

{'error': 'Unable to Authorize Request - Check Your Post Data', 'success': '0'}

这并不奇怪,因为我很难找到关于如何使用这些库进行调用和签名认证API请求的文档。我不知道该从哪里开始。

这是我代码的一部分:

import time
import requests
from requests-oauthlib import OAuth1Session

class Cryptsy:

    def __init__(self, APIKey, Secret):
        self.APIKey = APIKey
        self.Secret = Secret
        self.privateBaseURL = 'https://api.cryptsy.com/api'

    def private_api_query(self, method, payload={}):
        url = self.privateBaseURL
        session = OAuth1Session(self.APIKey, client_secret=self.Secret)
        payload['method'] = method
        payload['nonce'] = int(time.time())
        response = session.post(url, data=payload)
        js = response.json()
        return js

    def getMarkets(self):
        return self.private_api_query('getmarkets')

如你所见,我对nonce有点了解,但不确定在使用这些库时它是否必要。我知道请求需要被签名,但不太清楚如何让这些库按照我需要的方式去做。

当然,我也可以尝试使用urllib,但自从切换到Python 3后,我在使用它时遇到了麻烦,我更喜欢requests库(据说)更简单易用。

关于Cryptsy的API的更多信息可以在这里找到: https://www.cryptsy.com/pages/api

任何帮助都将非常感激。

1 个回答

2

Cryptsy并没有使用OAuth(至少他们的文档没有说他们在用)。相反,他们自己开发了认证方式。暂时不讨论这种方法的安全性,我们来看看你需要什么。

他们的文档不是很好,但根据我的理解,你需要:

  • 两个额外的头信息:Key(里面放你的公共API密钥)和Sign(里面放一个HMAC-SHA512的签名,用于请求体)
  • 一个请求体,内容类型为application/x-www-form-urlencoded,里面包含方法名称、方法参数和一个随机数(nonce)。

在请求中实现这一点比平常稍微复杂一些,但最简单的方法可能是自己写一个自定义的认证处理器。下面是一个例子:

from requests.auth import AuthBase
import hmac
import hashlib
import time

class CryptsyAuth(AuthBase):
    """Authenticates a given HTTP request using the Cryptsy Auth scheme"""
    def __init__(self, api_key, api_secret):
        self.key = api_key
        self.secret = api_secret

    def __call__(self, r):
        r.body += '&nonce=%d' % int(time.time())
        h = hmac.new(self.secret, r.body, hashlib.sha512).hexdigest()

        r.headers['Key'] = self.key
        r.headers['Sign'] = h
        return r

请注意,如果你不提供请求体,这个认证处理器会出错,但没关系,因为Cryptsy要求你必须提供。下面是如何使用它的:

class Cryptsy:

    def __init__(self, APIKey, Secret):
        self.APIKey = APIKey
        self.Secret = Secret
        self.privateBaseURL = 'https://api.cryptsy.com/api'
        self.session = requests.Session()

    def private_api_query(self, method, payload={}):
        url = self.privateBaseURL
        payload['method'] = method
        response = self.session.post(url, data=payload, auth=CryptsyAuth(self.APIKey, self.Secret))
        js = response.json()
        return js

    def getMarkets(self):
        return self.private_api_query('getmarkets')

撰写回答