Question

Je suis en train d'envoyer des notifications push à un iPhone en utilisant Python. J'ai exporté mon certificat et la clé privée dans un fichier p12 d'un accès trousseau puis converti en fichier pem en utilisant la commande suivante:

openssl pkcs12 -in cred.p12 -out cert.pem -nodes -clcerts

J'utilise APNSWrapper en Python pour la connexion .

Je lance le code suivant:

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()

Et puis je reçois le message d'erreur:

ssl.SSLError: (1, '_ssl.c:485: 
error:14094416:SSL routines:SSL3_READ_BYTES:sslv3 alert certificate unknown')

Quelqu'un peut-il me aider à ce sujet?

Était-ce utile?

La solution

J'ai récemment fait cela en utilisant Django - http: // leecutsco .de / 2009/07/14 / push-on-the-iphone /

Peut être utile? Il est fait usage de pas de bibliothèques supplémentaires autres que ceux qui sont inclus avec Python déjà. Ne serait pas grand-chose pour en extraire la méthode send_message () sur.

Autres conseils

Avez-vous envisagé package Twisted? Le code ci-dessous est tiré de ici :

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()

il y avait quelques bugs dans le code affiché à l'origine, voici donc une version corrigée qui fonctionne pour moi.

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()

Essayez de mettre à jour à la dernière version de APNSWrapper (0,4). Il y a accumulation à l'appui de l'outil de ligne de commande OpenSSL (OpenSSL s_client) maintenant.

J'ai essayé deux APNSWrapper et le code de Lee Peckham et ne pouvait pas obtenir de travailler sous Snow Leopard avec Python 2.6. Après beaucoup d'essais et erreurs, il a finalement travaillé avec pyOpenSSL.

Je l'ai déjà fait un post avec des détails et des extraits de code

scroll top