La connessione all'APN per iPhone Utilizzando Python
-
19-09-2019 - |
Domanda
Sto cercando di inviare notifiche push per iPhone con Python.Ho esportato il mio il certificato e la chiave privata in un file p12 da accesso portachiavi e poi convertiti in file pem utilizzando il seguente comando:
openssl pkcs12 -in cred.p12 -out cert.pem -nodes -clcerts
Sto utilizzando APNSWrapper in Python per la connessione.
Ho eseguito il seguente codice:
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()
E poi mi arriva il messaggio di errore:
ssl.SSLError: (1, '_ssl.c:485: error:14094416:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate unknown')
Qualcuno mi può aiutare su questo?
Soluzione
Recentemente ho fatto questo utilizzando Django http://leecutsco.de/2009/07/14/push-on-the-iphone/
Possono essere utili?Si sta facendo uso di librerie aggiuntive non diversi da quelli inclusi con Python già.Non ci vuole molto per estrarre il send_message() metodo.
Altri suggerimenti
Hai considerato la Twisted pacchetto?Il codice qui sotto è tratto dal qui:
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()
ci sono stati alcuni bug nella originariamente postato il codice, quindi, ecco una versione riveduta e corretta che funziona per me.
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()
Prova ad aggiornare all'ultima APNSWrapper versione (0.4).C'è build-a sostegno di openssl strumento a riga di comando (openssl s_client) ora.
Ho provato sia APNSWrapper
e Lee Peckham codice e non riuscivo a farlo funzionare sotto Snow Leopard con Python 2.6.Dopo un sacco di tentativi ed errori, infine, ha lavorato con pyOpenSSL
.
Ho già fatto un post con i dettagli e frammenti di codice qui quindi mi limiterò a vedere lì.