【问题标题】:What's the proper way to access Gravity Forms API in Python?在 Python 中访问 Gravity Forms API 的正确方法是什么?
【发布时间】:2019-07-22 19:55:53
【问题描述】:

我正在尝试使用 Python 通过他们的 REST API v2 访问 Gravity Forms 条目数据,但无法弄清楚如何正确进行身份验证。我应该使用基本身份验证还是 OAuth1?我从来没有成功使用过,所以示例代码会很有帮助。

我尝试了基本身份验证,这似乎是requests 模块的默认设置。

import requests

url = 'https://<INSERT DOMAIN HERE>/wp-json/gf/v2/entries'
auth = (<CONSUMER KEY>, <CONSUMER SECRET>)
r = requests.get(url, auth=auth)
print(r.status_code)

当基本身份验证不起作用时,我还尝试使用 requests_oathlibthis post 作为指导的 OAuth1,但我也无法使其正常工作。我不确定不同的密钥/令牌/秘密是什么或如何获得它们。我有一个来自 WordPress 仪表板的 Gravity Forms REST API 部分的“消费者密钥”和一个“消费者秘密”,仅此而已。

import requests
from requests_oauthlib import OAuth1

url = 'https://<INSERT DOMAIN HERE>/wp-json/gf/v2/entries'
auth = OAuth1('YOUR_APP_KEY', 'YOUR_APP_SECRET', 'USER_OAUTH_TOKEN', 'USER_OAUTH_TOKEN_SECRET')
r = requests.get(url, auth=auth)
print(r.status_code)

我也尝试关注requests_oauthlibhere 的文档,但我不确定在哪里使用哪个网址或采用哪个路径(会话与助手)。

Gravity Forms REST API documentation 表示,只要使用 HTTPS 发送请求,基本身份验证是可以接受的,而 HTTP 请求必须使用 OAuth1.0a。我也不能上班。但是,我知道我已经接近了,因为我可以让 Postman 应用程序使用 OAuth1 和 HMAC-SHA1“签名方法”的“Consumer Key”和“Consumer Secret”工作。

我希望收到 200 响应状态码,但无论我使用哪种类型的身份验证,我都会不断收到 401 响应状态码。

【问题讨论】:

    标签: python authentication python-requests gravityforms


    【解决方案1】:

    我不能 100% 确定所有的细微差别,但经过广泛的研究和反复试验,我得到了这个为自己工作。请随时添加建议。

    import requests
    import time
    import random
    import string
    import oauthlib.oauth1.rfc5849.signature as oauth
    from urllib.parse import quote_plus
    import os
    import json
    import datetime
    
    
    def create_nonce(N = 32): # randomly generated 32 character (recommended) string
        result = ''.join(random.choices(string.ascii_letters + string.digits, k = N))
        return result
    
    
    def create_signature(httpMethod, url, urlSuffix, nonce, timestamp, consumerKey, signatureMethod, version):
        consumerSecret = <INSERT_YOUR_CONSUMER_SECRET_HERE>
        # https://stackoverflow.com/a/39494701/5548564
        # In case of http://example.org/api?a=1&b=2 - the uri_query value would be "a=1&b=2".
        uri_query = urlSuffix
        # The oauthlib function 'collect_parameters' automatically ignores irrelevant header items like 'Content-Type' or
        # 'oauth_signature' in the 'Authorization' section.
        headers = {
            "Authorization": (
                f'OAuth realm="", '
                f'oauth_nonce={nonce}, '
                f'oauth_timestamp={timestamp}, '
                f'oauth_consumer_key={consumerKey}, '
                f'oauth_signature_method={signatureMethod}, '
                f'oauth_version={version}')}
        # There's no POST data here - in case it was: x=1 and y=2, then the value would be '[("x","1"),("y","2")]'.
        data = []
        params = oauth.collect_parameters(uri_query=uri_query,
                                          body=data,
                                          headers=headers,
                                          exclude_oauth_signature=True,
                                          with_realm=False)
        norm_params = oauth.normalize_parameters(params)
        base_string = oauth.construct_base_string(httpMethod, url, norm_params)
        signature = oauth.sign_hmac_sha1(base_string, consumerSecret, '')
        return quote_plus(signature)
    
    
    def send_request():
        url = <INSERT_URL_HERE>
        urlSuffix = "_labels=1"  # Addes array at end of json results including a map to the field labels
        httpMethod = "GET"
        consumerKey = <INSERT_CONSUMER_KEY_HERE>
        signatureMethod = "HMAC-SHA1"
        timestamp = str(int(time.time()))
        nonce = create_nonce()
        version = "1.0"
        signature = create_signature(httpMethod, url, urlSuffix, nonce, timestamp, consumerKey, signatureMethod, version)
        queryString = {"oauth_consumer_key": consumerKey,
                       "oauth_signature_method": signatureMethod,
                       "oauth_timestamp": timestamp,
                       "oauth_nonce": nonce,
                       "oauth_version": version,
                       "oauth_signature": signature}
        headers = {'User-Agent': "Testing/0.1",
                   'Accept': "*/*",
                   'Host': "<INSERT_YOUR_DOMAIN_HERE>",
                   'Accept-Encoding': "gzip, deflate",
                   'Connection': "keep-alive"}
        if urlSuffix:
            url = url + "?" + urlSuffix
        r = requests.request(httpMethod, url, headers=headers, params=queryString)
        if r.status_code == 200:
            dict = json.loads(r.text)
            return dict
        else:
            print(r.status_code)
            return None
    
    
    response = send_request()
    

    【讨论】:

      【解决方案2】:

      对于仍然需要此功能的任何人,通过反复试验,我发现他们将预期的身份验证位置更改为在查询中,而不是您在大多数 python 身份验证库中找到的标题。你可以这样改变它:

      import oauthlib
      from requests_oauthlib import OAuth1Session
      
      consumer_key = "banana"
      client_secret = "also banana"
      
      session = OAuth1Session(consumer_key, client_secret=consumer_secret, signature_type=oauthlib.oauth1.SIGNATURE_TYPE_QUERY)
      
      url = 'https:// YOUR URL /wp-json/gf/v2/entries'
      r = session.get(url)
      print(r.content)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-09
        相关资源
        最近更新 更多