使用 Python 连接到 iPhone 的 APNS
-
19-09-2019 - |
题
我正在尝试使用 Python 向 iPhone 发送推送通知。我已经导出了我的 证书和私钥 从钥匙串访问转换为 p12 文件,然后使用以下命令将其转换为 pem 文件:
openssl pkcs12 -in cred.p12 -out cert.pem -nodes -clcerts
我在用着 APNSWrapper 在 Python 中进行连接。
我运行以下代码:
deviceToken = 'Qun\xaa\xd ... c0\x9c\xf6\xca' # create wrapper wrapper = APNSNotificationWrapper('/path/to/cert/cert.pem', True) # create message message = APNSNotification() message.token(deviceToken) message.badge(5) # add message to tuple and send it to APNS server wrapper.append(message) wrapper.notify()
然后我收到错误消息:
ssl.SSLError: (1, '_ssl.c:485: error:14094416:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate unknown')
谁能帮我解决这个问题吗?
解决方案
我最近做此使用Django - 的http:// leecutsco由Matchi.com提供回到/ 2009/07/14 /推入式的-iphone /
可能有用吗?它利用的比那些包括在Python已经没有其他额外的库。不会花费太多提取send_message()方法进行。
其他提示
from struct import pack
from OpenSSL import SSL
from twisted.internet import reactor
from twisted.internet.protocol import ClientFactory, Protocol
from twisted.internet.ssl import ClientContextFactory
APNS_SERVER_HOSTNAME = "<insert the push hostname from your iPhone developer portal>"
APNS_SERVER_PORT = 2195
APNS_SSL_CERTIFICATE_FILE = "<your ssl certificate.pem>"
APNS_SSL_PRIVATE_KEY_FILE = "<your ssl private key.pem>"
class APNSClientContextFactory(ClientContextFactory):
def __init__(self):
self.ctx = SSL.Context(SSL.SSLv3_METHOD)
self.ctx.use_certificate_file(APNS_SSL_CERTIFICATE_FILE)
self.ctx.use_privatekey_file(APNS_SSL_PRIVATE_KEY_FILE)
def getContext(self):
return self.ctx
class APNSProtocol(Protocol):
def sendMessage(self, deviceToken, payload):
# notification messages are binary messages in network order
# using the following format:
# <1 byte command> <2 bytes length><token> <2 bytes length><payload>
fmt = "!cH32cH%dc" % len(payload)
command = 0
msg = struct.pack(fmt, command, deviceToken,
len(payload), payload)
self.transport.write(msg)
class APNSClientFactory(ClientFactory):
def buildProtocol(self, addr):
print "Connected to APNS Server %s:%u" % (addr.host, addr.port)
return APNSProtocol()
def clientConnectionLost(self, connector, reason):
print "Lost connection. Reason: %s" % reason
def clientConnectionFailed(self, connector, reason):
print "Connection failed. Reason: %s" % reason
if __name__ == '__main__':
reactor.connectSSL(APNS_SERVER_HOSTNAME,
APNS_SERVER_PORT,
APNSClientFactory(),
APNSClientContextFactory())
reactor.run()
有在最初发布代码的一些缺陷,所以这里有一个修正版本,为我的作品。
from struct import pack
from OpenSSL import SSL
from twisted.internet import reactor
from twisted.internet.protocol import ClientFactory, Protocol
from twisted.internet.ssl import ClientContextFactory
import binascii
import struct
APNS_SERVER_HOSTNAME = "gateway.sandbox.push.apple.com"
APNS_SERVER_PORT = 2195
APNS_SSL_CERTIFICATE_FILE = "<your ssl certificate.pem>"
APNS_SSL_PRIVATE_KEY_FILE = "<your ssl private key.pem>"
DEVICE_TOKEN = "<hexlified device token>"
MESSAGE = '{"aps":{"alert":"twisted test"}}'
class APNSClientContextFactory(ClientContextFactory):
def __init__(self):
self.ctx = SSL.Context(SSL.SSLv3_METHOD)
self.ctx.use_certificate_file(APNS_SSL_CERTIFICATE_FILE)
self.ctx.use_privatekey_file(APNS_SSL_PRIVATE_KEY_FILE)
def getContext(self):
return self.ctx
class APNSProtocol(Protocol):
def connectionMade(self):
print "connection made"
self.sendMessage(binascii.unhexlify(DEVICE_TOKEN), MESSAGE)
self.transport.loseConnection()
def sendMessage(self, deviceToken, payload):
# notification messages are binary messages in network order
# using the following format:
# <1 byte command> <2 bytes length><token> <2 bytes length><payload>
fmt = "!cH32sH%ds" % len(payload)
command = '\x00'
msg = struct.pack(fmt, command, 32, deviceToken,
len(payload), payload)
print "%s: %s" %(binascii.hexlify(deviceToken), binascii.hexlify(msg))
self.transport.write(msg)
class APNSClientFactory(ClientFactory):
def buildProtocol(self, addr):
print "Connected to APNS Server %s:%u" % (addr.host, addr.port)
return APNSProtocol()
def clientConnectionLost(self, connector, reason):
print "Lost connection. Reason: %s" % reason
def clientConnectionFailed(self, connector, reason):
print "Connection failed. Reason: %s" % reason
if __name__ == '__main__':
reactor.connectSSL(APNS_SERVER_HOSTNAME,
APNS_SERVER_PORT,
APNSClientFactory(),
APNSClientContextFactory())
reactor.run()
尝试更新到最新版本APNSWrapper(0.4)。有内置的支持OpenSSL的命令行工具(OpenSSL的的s_client.First)现在的。
我都尝试过 APNSWrapper
和 Lee Peckham 的代码,但无法让它在带有 Python 2.6 的 Snow Leopard 下工作。经过大量的试验和错误,它终于可以使用 pyOpenSSL
.
我已经发表了一篇包含详细信息和代码片段的帖子 这里 所以我会推荐你去那里。
不隶属于 StackOverflow