Вопрос

Я пытаюсь отправлять push-уведомления на iPhone с помощью Python.Я экспортировал свои сертификат и закрытый ключ в файл p12 из keychain access, а затем преобразовал его в pem-файл, используя следующую команду:

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

Я использую АПНСВраппер на 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.de/2009/07/14/push-on-the-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).

Я попробовал оба варианта APNSWrapper и код Ли Пекхэма, и не смог заставить его работать под Snow Leopard с Python 2.6.После долгих проб и ошибок это наконец сработало с pyOpenSSL.

Я уже опубликовал пост с подробностями и фрагментами кода здесь так что я просто направлю вас туда.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top