[英]APNS, how do I fix “unable to get local issuer certificate” error on raspberry Pi when program works on Mac?
I'm trying to send an iOS push notification through a python script that works on my Mac but the program gets the error "httpcore.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c: 1122)" 当我在我的树莓派上运行它时。 我尝试添加 GeoTrust 和新的 AAACertificateServices 证书,但也许我在那里做错了什么。 证书永远让我感到困惑,所以我非常感谢您的帮助。 我正在使用基于令牌的身份验证,所以我对错误首先指的是什么证书有点困惑......
在带有 Debian 的 Raspberry Pi 3 Model B 上运行。
整个 Traceback 是:
Traceback (most recent call last):
File "/home/jake/.local/lib/python3.9/site-packages/httpx/_exceptions.py", line 326, in map_exceptions
yield
File "/home/jake/.local/lib/python3.9/site-packages/httpx/_client.py", line 861, in _send_single_request
(status_code, headers, stream, ext) = transport.request(
File "/home/jake/.local/lib/python3.9/site-packages/httpcore/_sync/connection_pool.py", line 218, in request
response = connection.request(
File "/home/jake/.local/lib/python3.9/site-packages/httpcore/_sync/connection.py", line 93, in request
self.socket = self._open_socket(timeout)
File "/home/jake/.local/lib/python3.9/site-packages/httpcore/_sync/connection.py", line 119, in _open_socket
return self.backend.open_tcp_stream(
File "/home/jake/.local/lib/python3.9/site-packages/httpcore/_backends/sync.py", line 143, in open_tcp_stream
return SyncSocketStream(sock=sock)
File "/usr/local/opt/python-3.9.0/lib/python3.9/contextlib.py", line 135, in __exit__
self.gen.throw(type, value, traceback)
File "/home/jake/.local/lib/python3.9/site-packages/httpcore/_exceptions.py", line 12, in map_exceptions
raise to_exc(exc) from None
httpcore.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1122)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/jake/Programming/Security/MQTT/NotificationServer.py", line 73, in <module>
sendAlarmNotification()
File "/home/jake/Programming/Security/MQTT/NotificationServer.py", line 66, in sendAlarmNotification
r = client.post('{}/3/device/{}'.format(server, deviceToken), json=notification, headers=headers)
File "/home/jake/.local/lib/python3.9/site-packages/httpx/_client.py", line 992, in post
return self.request(
File "/home/jake/.local/lib/python3.9/site-packages/httpx/_client.py", line 733, in request
return self.send(
File "/home/jake/.local/lib/python3.9/site-packages/httpx/_client.py", line 767, in send
response = self._send_handling_auth(
File "/home/jake/.local/lib/python3.9/site-packages/httpx/_client.py", line 805, in _send_handling_auth
response = self._send_handling_redirects(
File "/home/jake/.local/lib/python3.9/site-packages/httpx/_client.py", line 837, in _send_handling_redirects
response = self._send_single_request(request, timeout)
File "/home/jake/.local/lib/python3.9/site-packages/httpx/_client.py", line 861, in _send_single_request
(status_code, headers, stream, ext) = transport.request(
File "/usr/local/opt/python-3.9.0/lib/python3.9/contextlib.py", line 135, in __exit__
self.gen.throw(type, value, traceback)
File "/home/jake/.local/lib/python3.9/site-packages/httpx/_exceptions.py", line 343, in map_exceptions
raise mapped_exc(message, **kwargs) from exc # type: ignore
httpx.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1122)
我的代码是
import httpx
import time
from jwcrypto import jwt, jwk
devServer = "https://api.sandbox.push.apple.com:443"
prodServer = "https://api.push.apple.com:443"
server = devServer
pemFilePath = "pushCerts/PushNotificationAuthKey_**********.p8"
# This generates an auth token with the current time, using our pem files
def generateAuthToken():
issueTime = int(time.time())
token = jwt.JWT( header={ "alg" : "ES256", "kid" : "**********"}, claims={ "iss": "********", "iat": issueTime} )
with open(pemFilePath, "rb") as pemfile:
key = jwk.JWK.from_pem(pemfile.read())
token.make_signed_token(key)
return token.serialize()
deviceToken = "long device token"
authToken = 'bearer ' + generateAuthToken()
pushType = 'alert'
expiration = '3600'
priority = '10'
topic = 'com.MyName.MyAppName'
headers = {
'authorization' : authToken,
'apns-push-type' : pushType,
'apns-expiration' : expiration,
'apns-priority' : priority,
'apns-topic' : topic
}
def sendAlarmNotification():
notification = { "aps" : { "alert": "Alarm Triggered!", "sound" : { "critical": 1, "name": "Alarm.caf", "volume": 1.0 }}}
client = httpx.Client(http2=True)
try:
r = client.post('{}/3/device/{}'.format(server, deviceToken), json=notification, headers=headers)
print(r)
finally:
client.close()
sendAlarmNotification()
此外,运行openssl s_client -connect api.sandbox.push.apple.com:443
回来后验证成功,所以我真的很困惑。
从这里开始: https://www.python-httpx.org/advanced/看起来您需要在 httpx 调用中指定 pem 文件:
导入httpx
r = httpx.get("https://example.org", verify="path/to/client.pem")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.