Netsuite REST Web Services API получает запрос вне Postman

#python #api #rest #postman #netsuite

#python #API #rest #postman #netsuite

Вопрос:

Привет, сообщество Stack Overflow, заранее спасибо за вашу помощь:

Вопрос для сообщества: вместо того, чтобы изобретать колесо oauth, есть ли какие-либо советы / рекомендации по созданию моей собственной подписи / одноразового номера oauth в моих запросах python GET для нового API Netsuite (REST Web Services; контекст вопроса см. Ниже)? Похоже, что другие люди, которые добились успеха в этом, сделали это методом проб и ошибок, что также является моим планом, но в идеале я хотел бы иметь меньше ошибок и, опять же, не изобретать велосипед. Любые советы, рекомендации, идеи приветствуются. См. Контекст ниже

Что: Попытка сделать запрос GET с использованием нового REST API Netsuite (REST Web Services). Это другой API, чем их SOAP / RESTlets.

Как: путем написания скрипта Python в коде Visual Studio. Мне удалось выполнить запрос в Postman. Я скопировал код в код Visual Studio, который Postman использовал для выполнения успешного запроса GET, и получил ответ 401 (см. Ниже).

Обнаруженная проблема: я получаю ответ 401, неверный логин. Нет официальной документации Netsuite о том, как обеспечить успешное взаимодействие с этим новым REST API за пределами Postman, поэтому после прочтения StackOverflow и других блогов / публикаций кажется, что мне нужно создать свой собственный oauth_signature, oauth_timestamp и oauth_nonce.

Postman ПОЛУЧАЕТ код запроса:

 import requests

url = "https://123456-sb1.suitetalk.api.netsuite.com/services/rest/query/v1/workbook/custworkbook12345/result"

payload = {}
headers = {
  'Authorization': 'OAuth realm="123456_SB1",oauth_consumer_key="123456789101112131415",oauth_token="123456789101112131415",oauth_signature_method="HMAC-SHA256",oauth_timestamp="123456789",oauth_nonce="123456789",oauth_version="1.0",oauth_signature="123456789101112131415"',
  'Cookie': 'NS_ROUTING_VERSION=LAGGING'
}

response = requests.request("GET", url, headers=headers, data = payload)

print(response.text.encode('utf8'))


  

Заранее спасибо!

Комментарии:

1. есть ли библиотека python oauth, которую вы можете использовать? я бы начал с этого, а не создавал заголовок самостоятельно. это значение заголовка oauth имеет некоторую сложность. что-то вроде oauthlib.readthedocs.io/en/latest/oauth1/client.html ?

2. Спасибо, Джош, я посмотрю на oauthlib и ознакомлюсь с тем, как это работает / попробую. Похоже, что он поддерживает HMAC-SHA256, есть ли что-нибудь, на что я должен обратить внимание при подписании с помощью HMAC-SHA256 против HMAC-SHA1?

3. я только что посмотрел на свой код, я использую HMAC-SHA256. и в oauth1 было что-то очень странное, например, вы должны указать signature_method как ‘HMAC-SHA256’, а затем также использовать вызов библиотеки хеширования python и фактически выполнить hmac, используя 256. надеюсь, какая бы библиотека python, которую вы в конечном итоге используете, делает все это тайно для вас, это сбивает с толку.

4. Одно интересное замечание, на случай, если оно вам поможет: одноразовый номер должен быть сгенерирован вовремя, чтобы запросить вызов. если вы сделаете что-то вроде сгенерировать его, а затем подождать 5 минут, вы получите 401, потому что одноразовый номер «истекает» примерно через 30-60 секунд.

5. И netsuite только что выпустил некоторое обновление о том, что realm является необязательным, я до сих пор не удосужился изучить его, но, к вашему сведению, realm может быть необязательным сейчас, а также документы netsuite могут быть ужасно устаревшими или ошибочными, как обычно.

Ответ №1:

Благодаря рекомендации Джоша (см. Комментарии к моему первоначальному вопросу) Я успешно использовал клиент oauth1 oauthlib для отправки запроса в коде Visual Studio. Одноразовый номер и подпись выглядят немного иначе, чем то, что Postman показывает в своем фрагменте кода, но это сработало. Для тех, кто пытается сделать то же самое с веб-службами Netsuite REST, я предлагаю пойти по этому пути.

Мой код, который отправил успешный запрос GET:

 import requests
import oauthlib.oauth1
import json


url = "https://12345-sb1.suitetalk.api.netsuite.com/services/rest/query/v1/dataset/custdataset1/result"

payload = {}

client = oauthlib.oauth1.Client('consumer key', client_secret='12345',
    resource_owner_key='12345', resource_owner_secret='12345', realm='12345_SB1',signature_method="HMAC-SHA256")
url, headers, body = client.sign('https://4635201-sb4.suitetalk.api.netsuite.com/services/rest/query/v1/dataset/custdataset1/result')


response = requests.request("GET", url, headers=headers, data = payload)

print(response.text.encode('utf8'))

  

Несколько дополнительных полезных замечаний —

  • Я тестирую это в песочнице Netsuite, отсюда и область «12345_SB1». Если вы не находитесь в песочнице, вам не нужен символ подчеркивания SB. Просто используйте свой идентификатор учетной записи.
  • Я извлекаю отчет Netsuite Analytics, который в настоящее время все еще находится в бета-версии для нового API (REST Web Services).
  • Я использовал Python oauthlib, который рекомендовал Джош, и я рекомендую вам сделать то же самое, ссылка здесь

Комментарии:

1. Как вам удалось получить ваш consumer_key, client_secret, resource_owner_key и resource_owner_secret? Я использовал SHA1 в течение многих лет, и использовались ключи / секреты, поставляемые с интеграцией. Но теперь я пытаюсь переключиться на SHA256, и те же ключи выдают недопустимые ошибки входа в систему.

2. При использовании параметров в запросе GET их не нужно включать в URL, который вы используете для получения заголовков? Я получаю несанкционированный ответ ТОЛЬКО при наличии параметра q (запроса) (в вызове списка JournalEntry). Конечно, когда я не предоставляю никаких параметров, я также не получаю результатов (но журнал аудита входа в систему показывает успешный вход в этот экземпляр).