如何在 Python 中为 Netsuite Rest API 调用生成 OAuth 标头 - 当前收到 401 错误,但它可以在具有相同环境变量的 Postman 中工作

问题描述 投票:0回答:1

我需要帮助获取 python 程序来针对 netsuite Rest api 进行身份验证。

首先,我能够使用postman成功调用API。我正在使用 Netsuite 的 您可以在这里下载邮递员教程

我已成功完成所有必要的步骤,在 Netsuite 中创建集成应用程序并获取 消费者密钥和秘密以及我自己的用户令牌密钥和秘密。我已将这些值放入 邮递员,以及正确的 url 和帐户 ID,邮递员从 收到 200 响应 网络套件。

如果我将邮递员中的代码复制到 python 文件中并在终端中执行,它也可以工作。 所以我的挑战是我需要生成

timestamp
nonce
oauth_signature
,因为 这些值总是会改变每个请求。

下面的代码完成了所有这些事情并形成了一个 适当的要求。我从这个tutorial得到了代码 我应该注意的一件事是我不明白这篇文章中“已保存的搜索”的含义,并且 “部署 ID”。我故意排除了这行代码,因为我不确定它是什么:

data = 'deploy=' +  + str(deployment_id) + "&"
,以及这一行:
data += 'script=' + str(script_id)

最后,当我从邮递员复制之前的时间戳和随机数并将它们硬编码到我的代码中时, 打印的 oauth 签名与邮递员中的签名不同。我不知道为什么会这样,但我从来没有 能够完美地复制邮递员正在做的事情。

这是我的代码:

import base64
import hashlib
import hmac
import math
import os
import random
import time
from dotenv import load_dotenv
import urllib
import requests
load_dotenv()


CONSUMER_KEY = os.getenv("CONSUMER_KEY")
CONSUMER_SECRET = os.getenv("CONSUMER_SECRET")
TOKEN_SECRET = os.getenv("TOKEN_SECRET")
TOKEN_ID = os.getenv("TOKEN_ID")
ACCOUNT_ID = os.getenv("ACCOUNT_ID")
ENDPOINT = f'{os.getenv("REST_SERVICES")}record/v1/customer/1'
SIGN_METHOD = "HMAC-SHA256"
OAUTH_VERSION = "1.0"


def getAuthNonce():
    nonce_text = ''
    length = 11
    possible= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
    for i in range(length):
        nonce_text += possible[math.floor(random.uniform(0, 1) * len(possible))]
    return nonce_text


def getSignature(BASE_URL, HTTP_METHOD, OAUTH_NONCE, TIME_STAMP):
    data = 'oauth_consumer_key' + "=" + CONSUMER_KEY + "&"
    data += 'oauth_nonce' + "=" + OAUTH_NONCE + "&"
    data += 'oauth_signature_method' + "=" + SIGN_METHOD + "&"
    data += 'oauth_timestamp' + "=" + str(TIME_STAMP) + "&"
    data += 'oauth_token' + "=" + TOKEN_ID + "&"
    data += 'oauth_version' + "=" + OAUTH_VERSION + "&"
    signatureValue = HTTP_METHOD + '&' + urllib.parse.quote(BASE_URL, safe='~()*!.\'') + '&' + urllib.parse.quote(data,safe='~()*!.\'')
    signatureKey = urllib.parse.quote(CONSUMER_SECRET, safe='~()*!.\'') + '&' + urllib.parse.quote(TOKEN_SECRET,safe='~()*!.\'')
    signatureValue = bytes(signatureValue, 'utf-8')
    signatureKey = bytes(signatureKey, 'utf-8')
    shaData = hmac.new(signatureKey, signatureValue, digestmod=hashlib.sha256).digest()

    base64EncodedData = base64.b64encode(shaData)
    oauth_signature = base64EncodedData.decode('utf-8')
    oauth_signature = urllib.parse.quote(oauth_signature, safe='~()*!.\'')
    return oauth_signature


def createHeader():
    BASE_URL = ENDPOINT
    OAUTH_NONCE = getAuthNonce()
    TIME_STAMP = round(time.time())
    HTTP_METHOD = "GET"
    oauth_signature = getSignature(BASE_URL, HTTP_METHOD, OAUTH_NONCE, TIME_STAMP)

    OAuthHeader = 'OAuth '
    OAuthHeader += 'realm="' + ACCOUNT_ID + '",'
    OAuthHeader += 'oauth_token="' + TOKEN_ID + '",'
    OAuthHeader += 'oauth_consumer_key="' + CONSUMER_KEY + '",'
    OAuthHeader += 'oauth_nonce="' + OAUTH_NONCE + '",'
    OAuthHeader += 'oauth_timestamp="' + str(TIME_STAMP) + '",'
    OAuthHeader += 'oauth_signature_method="' + SIGN_METHOD + '",'
    OAuthHeader += 'oauth_version="1.0",'
    OAuthHeader += 'oauth_signature="' + oauth_signature + '"'

    headers = {
        "Authorization": OAuthHeader,
        "prefer": "transient",
        "Cookie": "NS_ROUTING_VERSION=LAGGING"
    }
    return headers


headers = createHeader()
response = requests.request("GET", ENDPOINT, headers=headers, data={})
print(response)
print(response.text)

这是我从终端收到的错误

$ python src/try.py
<Response [401]>
{"type":"https://www.rfc-editor.org/rfc/rfc9110.html#section-15.5.2","title":"Unauthorized","status":401,"o:errorDetails":[{"detail":"Invalid login attempt. For more details, see the Login Audit Trail in the NetSuite UI at Setup > Users/Roles > User Management > View Login Audit Trail.","o:errorCode":"INVALID_LOGIN"}]}

这是我的邮递员供参考(404 响应是一件好事,因为它已通过身份验证)

请帮助我获得 200 响应,这样我就可以开始使用这个 api 来发挥我的优势,并且我可以停止 快疯了。

python rest oauth netsuite netsuite-rest-api
1个回答
0
投票

有运气吗? 即使我也在为此挣扎。

© www.soinside.com 2019 - 2024. All rights reserved.