Запрос Python HTTPS SSLError CERTIFICATE_VERIFY_FAILED

ПИТОН

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)'),))

Ваш Nim-код может неправильно проверять сертификат в соответствии со стандартами. Без сертификата у нас нет возможности узнать, есть ли поле, которое может вызвать такое поведение.

Bakuriu 22.10.2018 19:58
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
968
2

Ответы 2

Модуль requests будет проверять сертификат, полученный от сервера, так же, как это делал бы браузер. Вместо того, чтобы иметь возможность щелкнуть и сказать «добавить исключение», как в браузере, requests вызовет это исключение.

Однако есть способ обойти это: попробуйте добавить verify=False к вашему вызову post.

Я бы предпочел исправить хранилище сертификатов / сертификатов, а не просто отключать проверку сертификата ...

Bakuriu 22.10.2018 19:59

Верно, но в среде разработки, которая может быть неблагоразумной, и в среде производства (например, не принадлежащей вам) это может быть невозможно. Это поможет ему справиться с этим, но вы правы, всегда доверять недействительным сертификатам небезопасно.

wholevinski 22.10.2018 20:00

Правильно, Ним вроде не проверяет сертификат. Verify = False действительно решает проблему, но, возможно, я не должен этого делать, как говорит Бакуриу.

UrbKr 22.10.2018 20:21

Мне придется проконсультироваться с людьми, которые предоставили мне API, относительно сертификата. Я приму ответ, когда сделаю это

UrbKr 22.10.2018 20:22

@UrbKr Как сказал Бакури в своем комментарии к вашему вопросу, получение оригинального сертификата тоже может помочь. Если это ненадежный ЦС, вы можете добавить их сертификат ЦС как доверенный. Если это что-то вроде несоответствующего URL-адреса или истек срок действия сертификата, им определенно необходимо исправить это на своей стороне.

wholevinski 22.10.2018 20:27

@UrbKr К вашему сведению, если вы посетите URL-адрес в браузере, вы, вероятно, сможете получить более подробную информацию о том, что не так с сертификатом.

wholevinski 22.10.2018 20:28

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, чтобы проверить, что не так.

Другие вопросы по теме