Yelp API 产生无效签名错误

Yelp API Produces Invalid Signature Error

在查看了几篇在线文章、Whosebug 和 Yelp Google 小组之后,我一直无法找出问题所在,因为我的 Invalid Signature 错误产生了Yelp API 请求。

这是确切的错误:

{'error': {'text': 'Signature was invalid', 'description': 'Invalid signature. Expected signature base string: [some text here with keys]}}

以及我编写的代码:

import rauth
import time

def get_results():

    #Obtain these from Yelp's manage access page
    consumer_key = ''
    consumer_secret = ''
    token = ''
    token_secret = ''

    session = rauth.OAuth1Session(
            consumer_key = consumer_key
            ,consumer_secret = consumer_secret
            ,access_token = token
            ,access_token_secret = token_secret)

    request = session.get("http://api.yelp.com/v2/search?location=Boston&term=food")

    #Transforms the JSON API response into a Python dictionary
    data = request.json()
    print(data)
    session.close()

    return data

if __name__=="__main__":
    print(get_results())

那么到底是什么导致了这个错误?在这次尝试之前我做了一些修改,之前的尝试我也遇到了类似的错误;除了有一次我只收到“无效签名”错误,没有“期望签名基础字符串”消息

根据 docs

进行身份验证还有更多步骤

发出请求

Each request must contain the following OAuth protocol parameters:

OAuth Parameter Value
oauth_consumer_key  Your OAuth consumer key (from Manage API Access).
oauth_token The access token obtained (from Manage API Access).
oauth_signature_method  hmac-sha1
oauth_signature The generated request signature, signed with the oauth_token_secret obtained (from Manage API Access).
oauth_timestamp Timestamp for the request in seconds since the Unix epoch.
oauth_nonce A unique string randomly generated per request.

These parameters may be passed in the HTTP (Authorization) header as URL query keys or in the POST data. Generating the OAuth signature is done by applying the HMAC-SHA1 with the oauth_token_secret. You may view your OAuth consumer key at Manage API Access. OAuth libraries are available to generate these requests.

您没有传递必需的 oauth_timestamp 或应用 HMAC-SHA1,因此您收到 Invalid Signature 错误,上面的文档中清楚地概述了您需要发送的内容。

还有一个实际的 python yelp api you could use but to make a request you can use the example below based on the request function from the example code: 使用 oauth2requests 发出请求:

import requests
import oauth2

def request(url, url_params=None):
    consumer_key = ""
    consumer_secret = ""
    token = ""
    token_secret =""
    url_params = url_params or {}
    consumer = oauth2.Consumer(consumer_key, consumer_secret)
    oauth_request = oauth2.Request(method="GET", url=url, parameters=url_params)

    oauth_request.update(
        {
            'oauth_nonce': oauth2.generate_nonce(),
            'oauth_timestamp': oauth2.generate_timestamp(),
            'oauth_token': token,
            'oauth_consumer_key': consumer_key
        }
    )
    token = oauth2.Token(token, token_secret)
    oauth_request.sign_request(oauth2.SignatureMethod_HMAC_SHA1(), consumer, token)
    signed_url = oauth_request.to_url()

    print(u'Querying {0} ...'.format(url))

    return requests.get(signed_url).json()

使用您的 url 输出整个负载 json,其开头是:

Querying http://api.yelp.com/v2/search?location=Boston&term=food ...
{'region': {'center': {'longitude': -71.05460875, 'latitude': 42.35028894954365}, 'span': {'latitude_delta': 0.0325510910039668, 'longitude_delta': 0.04668455000000904}}, 'total': 8351, 'businesses': [{'name': "Giacomo's Ristorante", 'url': 'http://www.yelp.com/biz/giacomos-ristorante-boston', 'mobile_url': 'http://m.yelp.com/biz/giacomos-ristorante-boston', 'rating_img_url_large': 'http://s3-media2.fl.yelpcdn.com/assets/2/www/img/ccf2b76faa2c/ico/stars/v1/stars_large_4.png', 'phone': 
...............................................................
...............................................................

我不确定 api 是否支持 python 3 但上面的代码是用 python3 和 python2 测试的,它工作正常,可以安装oauth2 你可以简单 pip install oauth2 如果你没有安装 requests 也是如此。

另一个常见问题是服务器时间不同步。在 linux 上,可以 运行

sudo ntpdate -s time.nist.gov