2011-04-26 12 views
10

Estoy intentando implementar Apple Push Notification con python y django.Error de SSL al implementar Apple Push Notification

estoy usando biblioteca siguiente para implementarlo

http://leepa.github.com/django-iphone-push/

Aquí está mi código que crean que enviar el mensaje

from django.http import HttpResponse 
from django.utils import simplejson 
import json 
from push.models import iPhone 

def SendMessage(request,data): 

     t = iPhone('XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX XXXXXXXX ') # 64 digit token 
     t.send_message("hi") # at this line i am getting ERROR 
     return HttpResponse(data,mimetype='application/javascript') 

settings.py

import os 
PROJECT_ROOT = '/' 

# Full path to the APN Certificate/Private Key .pem 
IPHONE_SANDBOX_APN_PUSH_CERT = os.path.join(PROJECT_ROOT, "apns-dev-tubeteam.pem") 
IPHONE_LIVE_APN_PUSH_CERT = os.path.join(PROJECT_ROOT, "apns-dev-tubeteam.pem") 

# Set this to the hostname for the outgoing push server 
IPHONE_SANDBOX_APN_HOST = 'gateway.sandbox.push.apple.com' 
IPHONE_LIVE_APN_HOST = 'gateway.push.apple.com' 

# Set this to the hostname for the feedback server 
IPHONE_SANDBOX_FEEDBACK_HOST = 'feedback.sandbox.push.apple.com' 
IPHONE_LIVE_FEEDBACK_HOST = 'feedback.push.apple.com' 

error

[Errno 336265218] _ssl.c:337: error:140B0002:SSL routines:SSL_CTX_use_PrivateKey_file:system lib 

Puede alguien por favor dígame cómo deshacerse de ella.

+0

¿HABÍA LEÍDO el error? Claramente hay un problema con su token de 64 dígitos o su certificado SSL, o ambos. ¿Seguiste las instrucciones para configurar tus certificados? – jathanism

+0

Bueno, tengo un archivo .pem y he especificado la ruta de ese archivo. Ahora no estoy al tanto de la configuración de los certificados, ¿me puede decir en detalle – Hunt

Respuesta

16

Tuve exactamente el mismo problema. Resulta que fue un error simple: cometí un error en IPHONE_SANDBOX_APN_PUSH_CERT y python no pudo ubicar mi certificado. Una vez que lo señalé a la ubicación correcta, comenzó a funcionar.

Tenga en cuenta que es posible que desee volver a verificar su certificado de primera línea de comandos usando openssl, tales como:

openssl x509 -text -in cert.pem 

que le dará la información textual sobre su certificado, su validez, etc.

Además, vuelva a verificar los permisos de archivo del archivo de certificado (el proceso de Python debe tener suficientes derechos para acceder a él).

+2

+1 "no se pudo encontrar el certificado". En mi caso, solo fue un error tipográfico en el nombre del archivo. Realmente se siente como 'ssl.wrap_socket' podría arrojar un simple" archivo no encontrado "en lugar de dejar que el error SSL burbujee – ckhan

+0

También vale la pena señalar que aparentemente Apple podría cerrar la conexión si intentas enviar demasiados mensajes push a unregistered dispositivos (fuente: https://github.com/jleclanche/django-push-notifications/issues/69#issuecomment-53712129) – gregoltsov

-3

utilizar este código:

#!/usr/bin/python2.7 

import socket 
import ssl 
import json 
import struct 
import argparse 



APNS_HOST = ('gateway.sandbox.push.apple.com', 2195) 


class Payload: 
    PAYLOAD = '{"aps":{${MESSAGE}${BADGE}${SOUND}}}' 
    def __init__(self): 
     pass 

    def set_message(self, msg): 
     if msg is None: 
      self.PAYLOAD = self.PAYLOAD.replace('${MESSAGE}', '') 
     else: 
      self.PAYLOAD = self.PAYLOAD.replace('${MESSAGE}', '"alert":"%s",' % msg) 

    def set_badge(self, num): 
     if num is None: 
      self.PAYLOAD = self.PAYLOAD.replace('${BADGE}', '') 
     else: 
      self.PAYLOAD = self.PAYLOAD.replace('${BADGE}', '"badge":%s,' % num) 

    def set_sound(self, sound): 
     if sound is None: 
      self.PAYLOAD = self.PAYLOAD.replace('${SOUND}', '') 
     else: 
      self.PAYLOAD = self.PAYLOAD.replace('${SOUND}', '"sound":"%s",' % sound) 

    def toString(self): 
     return (self.PAYLOAD.replace('${MESSAGE}','').replace('${BADGE}','').replace('${SOUND}','')) 

def connectAPNS(host, cert): 
    ssl_sock = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM), certfile = cert) 
    ssl_sock.connect(APNS_HOST) 
    return ssl_sock 

def sendNotification(sslSock, device, message, badge, sound): 
    payload = Payload() 
    payload.set_message(message) 
    payload.set_badge(badge) 
    payload.set_sound(sound) 
    payloadAsStr = payload.toString() 

    format = '!BH32sH%ds' % len(payloadAsStr) 
    binaryDeviceToken = device.replace(' ','').decode('hex') 
    binaryNotification = struct.pack(format, 0, 32, binaryDeviceToken, len(payloadAsStr), payloadAsStr) 

    print ("sending payload: ["+payloadAsStr+"] as binary to device: ["+device+"]") 
    sslSock.write(binaryNotification) 

def printUsageAndExit(): 
    print("msg2ios - Version 0.1\nmsg2IOS.py -d <device> -m <message> -s[plays sound] -b <badgeint> -c <certBundlePath>") 
    exit(1) 

if __name__ == '__main__': 
    parser = argparse.ArgumentParser() 
    parser.add_argument('-d', '--device') 
    parser.add_argument('-m', '--message') 
    parser.add_argument('-s', '--sound') 
    parser.add_argument('-b', '--badge') 
    parser.add_argument('-c', '--cert') 
    args = parser.parse_args() 

    if (args.device is None) or ((args.message is None) and (args.sound is None) and (args.badge is None)) or (args.cert is None): 
     printUsageAndExit() 

    sslSock = connectAPNS(APNS_HOST, args.cert) 
    sendNotification(sslSock, args.device, args.message, args.badge, args.sound) 
    sslSock.close() 
+5

Alguna explicación aquí sería útil. – casperOne

-1

mi solución fue que al crear mi archivo .pem establecí una contraseña en blanco y asumí que no significaba ninguna contraseña. entonces el servidor aún esperaba usar una contraseña. tuve que eliminar manualmente la contraseña.

aquí es un poco de cómo guiar si ayuda a nadie:

NOTA: necesidad de seguir las instrucciones de la página web de desarrolladores de Apple para crear el certificado primera luego exportar el.archivo p12, mediante la exportación de la clave privada incrustada que se crea (en 'acceso de llavero'), NO el certificado real ----------------------- ------------- ------------------------------------ PARA DESARROLLO CERT: Después de obtener el archivo p12, debe convertirse al formato PEM ejecutando este comando desde la terminal: $ openssl pkcs12 -clcerts -nokeys -out apns-dev-cert.pem -in apns_dev. p12 $ openssl pkcs12 -nocerts -out apns-dev-key.pem -in apns_dev.p12

Si tiene Para eliminar la frase de contraseña, ejecute lo siguiente: (NOTA: al usar una contraseña 'en blanco' al exportar/convertir, todavía se establece una contraseña, , por lo tanto, debe ejecutar lo siguiente si no desea tener contraseña) $ openssl rsa -in apns-dev-key.pem -out apns-dev-key-noenc.pem

Finalmente, debe combinar los archivos key y cert en un archivo apns-dev.pem que usaremos al conectarnos a APN:

$ cat APN-dev-cert.pem APN-dev-key-noenc.pem> APN-dev.pem

---------------- ------ ------------- PARA PRODUCCIÓN CERT: Después de obtener el archivo p12, debe convertirse al formato PEM ejecutando este comando desde la terminal: $ openssl pkcs12 -clcerts -nokeys salida privado APN-prod-cert.pem -en apns_prod.p12 $ openssl pkcs12 -nocerts salida privado APN-prod-key.pem -en apns_prod.p12

Si desea eliminar la contraseña ejecute el siguiente: (NOTA: al usar una contraseña 'en blanco' al exportar/convertir, todavía se establece una contraseña, , por lo tanto, debe ejecutar lo siguiente si no desea tener una contraseña) $ openssl rsa -in apns-prod-key.pem -out apns-prod-key-noenc.pem

Por último, es necesario combinar los archivos de clave y cert en un archivo de APN-dev.pem vamos a utilizar cuando se conecta a APN:

$ gato APN-prod-cert.pem APN-prod-key- noenc.pem> apns-prod.pem

Cuestiones relacionadas