Интеграция AppEngine Paypal, обеспечивающая SSLCertificateError на локальном хосте с использованием Python

Я интегрирую paypalrestsdk в мой проект AppEngine. Когда, используя свой локальный dev_appserver, я пытаюсь создать платеж в песочнице PayPal, у меня появляется следующая ошибка:

SSLCertificateError: Invalid and/or missing SSL certificate for URL: https://api.sandbox.paypal.com/v1/oauth2/token

Итак, я попытался предоставить правильный файл pem, скачав его отсюда и настроив правильный ssl_option атрибут:

# Setting up the correct path to the .pem file
cert = os.path.join(ROOT, 'certs/api.sandbox.paypal.com_SHA-2_01132018.pem')
logger.info("Using SSL certificate: %s", cert)
return Api(
    mode=get_paypal_environment(), # sandbox or live
    client_id=flask.current_app.config["PAYPAL_CLIENT_ID"],
    client_secret=flask.current_app.config["PAYPAL_CLIENT_SECRET"],
    ssl_options={"cert": cert}
)

Здесь находится документация PayPalRestSDK, в которой подробно описывается, как предоставить сертификат. Я дважды проверил правильность созданного пути.

Я нашел здесь сообщение об ошибке, в котором говорится о схожей проблеме.

Кроме того, я попробовал решение, предложенное здесь, и до сих пор не работает.

На живом экземпляре, в appspot, все это работает отлично.

Вот соответствующая часть моих требований.txt:

Flask==0.10.1
itsdangerous==0.24
paramiko==1.15.1
pycrypto==2.6.1
Flask-OAuthlib==0.9.1
google-api-python-client==1.4.0
paypalrestsdk==1.11.1
requests[security]==2.9.1

У кого-нибудь есть такая же проблема?

1 ответ

Хорошо, я полагал, что решил это, по крайней мере, в моем случае, который я опишу ниже.

Похоже, это связано с двумя проблемами:

Проблема № 1) PayPal мигрирует на поддержку только TLS 1.2 и начал с переключения URL-адресов песочницы с производственными URL-адресами, которые появятся позже. Это объясняет, почему что-то ломается только при подключении из песочницы, и почему раньше работало, но не сейчас. Подробнее об этом здесь.

Проблема № 2) Моя локальная установка Python не поддерживала TLS 1.2. Вот простой способ проверить:

$ python
>>> import ssl
>>> print ssl._PROTOCOL_NAMES

Если ты не видишь PROTOCOL_TLSv1_2 в списке, это определенно проблема. В моем случае я использовал встроенную версию на Python для Mac OS X 10.11, в которой была встроена довольно старая версия на OpenSSL.

Так как это исправить? Ну, в моем случае это работало довольно хорошо (скопировано в основном отсюда):

$ brew update
$ brew install openssl
$ brew link openssl --force 
$ brew install python --with-brewed-openssl
$ sudo ln -s /usr/local/Cellar/python/2.7.11/bin/python /usr/local/bin/python

Теперь, если вы запустите тест, который я перечислил выше, вы должны увидеть протокол 1.2 в списке.

Это должно заставить все работать снова, удачи!

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