ПИТОН
import requests
url = "https://REDACTED/pb/s/api/auth/login"
r = requests.post(
url,
data = {
'username': 'username',
'password': 'password'
}
)
НИМ
import httpclient, json
let client = newHttpClient()
client.headers = newHttpHeaders({ "Content-Type": "application/json" })
let body = %*{
"username": "username",
"password": "password"
}
let resp = client.request("https://REDACTED.com/pb/s/api/auth/login", httpMethod = httpPOST, body = $body)
echo resp.body
Я вызываю API, чтобы получить данные. Запустив код Python, я получаю трассировку ниже. Однако код нима работает отлично, поэтому должно быть что-то не так с кодом или настройкой python.
Я использую Python версии 2.7.15. запрашивает версию библиотеки 2.19.1
Traceback (most recent call last):
File "C:/Python27/testht.py", line 21, in <module>
"Referer": "https://REDACTED.com/pb/a/"
File "C:\Python27\lib\site-packages\requests\api.py", line 112, in post
return request('post', url, data=data, json=json, **kwargs)
File "C:\Python27\lib\site-packages\requests\api.py", line 58, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 512, in request
resp = self.send(prep, **send_kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 622, in send
r = adapter.send(request, **kwargs)
File "C:\Python27\lib\site-packages\requests\adapters.py", line 511, in send
raise SSLError(e, request=request)
SSLError: HTTPSConnectionPool(host='REDACTED.com', port=443): Max retries exceeded with url: /pb/s/api/auth/login (Caused by SSLError(SSLError(1, u'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:726)'),))
Модуль requests
будет проверять сертификат, полученный от сервера, так же, как это делал бы браузер. Вместо того, чтобы иметь возможность щелкнуть и сказать «добавить исключение», как в браузере, requests
вызовет это исключение.
Однако есть способ обойти это: попробуйте добавить verify=False
к вашему вызову post
.
Я бы предпочел исправить хранилище сертификатов / сертификатов, а не просто отключать проверку сертификата ...
Верно, но в среде разработки, которая может быть неблагоразумной, и в среде производства (например, не принадлежащей вам) это может быть невозможно. Это поможет ему справиться с этим, но вы правы, всегда доверять недействительным сертификатам небезопасно.
Правильно, Ним вроде не проверяет сертификат. Verify = False действительно решает проблему, но, возможно, я не должен этого делать, как говорит Бакуриу.
Мне придется проконсультироваться с людьми, которые предоставили мне API, относительно сертификата. Я приму ответ, когда сделаю это
@UrbKr Как сказал Бакури в своем комментарии к вашему вопросу, получение оригинального сертификата тоже может помочь. Если это ненадежный ЦС, вы можете добавить их сертификат ЦС как доверенный. Если это что-то вроде несоответствующего URL-адреса или истек срок действия сертификата, им определенно необходимо исправить это на своей стороне.
@UrbKr К вашему сведению, если вы посетите URL-адрес в браузере, вы, вероятно, сможете получить более подробную информацию о том, что не так с сертификатом.
However, the nim code works perfectly so there must be something wrong with the python code or setup.
На самом деле ваш код или установка Python менее виноваты, а вместо этого код nim
или лучше значения по умолчанию в библиотеке httpclient
. В документации для nim
можно увидеть, что httpclient.request
использует контекст SSL, возвращаемый getDefaultSSL
по умолчанию, который, согласно этот код, создает контекст, который не проверяет сертификат:
proc getDefaultSSL(): SSLContext =
result = defaultSslContext
when defined(ssl):
if result == nil:
defaultSSLContext = newContext(verifyMode = CVerifyNone)
Вместо этого ваш код Python пытается правильно проверить сертификат, поскольку библиотека requests
делает это по умолчанию. И он не может проверить сертификат, потому что что-то не так - либо с вашей настройкой, либо с сервером.
Неясно, кто выпустил сертификат для вашего сайта, но если его нет в вашем хранилище ЦС по умолчанию, вы можете использовать аргумент verify
для requests
, чтобы указать ЦС издателя. Подробнее см. эта документация.
Если сайт, к которому вы пытаетесь получить доступ, работает с браузером, но не работает с вашей программой, возможно, он использует специальный ЦС, который был добавлен в браузер как доверенный (например, сертификат компании). Браузеры и Python используют разные хранилища доверенных сертификатов, поэтому этот добавленный сертификат необходимо добавить в Python или, по крайней мере, в вашу программу как доверенный. Также может быть проблема с настройкой сервера. Браузеры иногда могут обойти такие проблемы, как отсутствие промежуточного сертификата, но Python этого не делает. В случае общедоступного сайта вы можете использовать SSLLabs, чтобы проверить, что не так.
Ваш Nim-код может неправильно проверять сертификат в соответствии со стандартами. Без сертификата у нас нет возможности узнать, есть ли поле, которое может вызвать такое поведение.