我正在尝试使用python和django实现Apple推送通知。
我正在使用以下库来实现它
http://leepa.github.com/django-iphone-push/
这是我创建发送消息的代码
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'
错误
[Errno 336265218] _ssl.c:337: error:140B0002:SSL routines:SSL_CTX_use_PrivateKey_file:system lib
任何人都可以告诉我如何摆脱它。
答案 0 :(得分:16)
我遇到了完全相同的问题。事实证明这是一个简单的错误 - 我在IPHONE_SANDBOX_APN_PUSH_CERT中遇到了错误,而python无法找到我的证书。一旦我将它指向正确的位置,它就开始工作了。
请注意,您可能希望首先使用openssl命令行仔细检查您的证书,例如:
openssl x509 -text -in cert.pem
这将为您提供有关您的证书,其有效性等的文本信息。
另外,仔细检查证书文件的文件权限(python进程必须具有足够的权限才能访问它)。
答案 1 :(得分:0)
就我而言,对我有用的是下面的内容:
使用完整路径,如
apns = APNs(use_sandbox=True, cert_file='/usr/local/etc/cert.pem', key_file='/usr/local/etc/key.pem')
而不是
apns = APNs(use_sandbox=True, cert_file='cert.pem', key_file='key.pem')
答案 2 :(得分:-1)
我的解决方案是,在创建我的.pem文件时,我设置了一个空密码,并假设它没有密码。所以服务器仍然希望使用密码。我不得不手动删除密码。
这里有一点如何指导,如果它可以帮助任何人:
注意:需要按照Apple开发者网站的说明首先创建证书 然后导出.p12文件, 通过导出创建的嵌入式私钥(在'keychain access'中), 不是实际的证书 ------------------------------------ ------------------------------------ FOR DEVELOPMENT CERT: 获取p12文件后,需要通过终端执行此命令将其转换为PEM格式: $ 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
如果您想删除密码,请执行以下操作: (注意:导出/转换时使用'空白'密码,仍然确实设置了密码, 因此,如果您打算没有密码,您仍应执行以下操作) $ openssl rsa -in apns-dev-key.pem -out apns-dev-key-noenc.pem
最后,您需要将密钥和证书文件合并到我们将在连接到APNS时使用的apns-dev.pem文件中:
$ cat apns-dev-cert.pem apns-dev-key-noenc.pem> APNS-dev.pem
------------------------------------ 生产CERT: 获取p12文件后,需要通过终端执行此命令将其转换为PEM格式: $ openssl pkcs12 -clcerts -nokeys -out apns-prod-cert.pem -in apns_prod.p12 $ openssl pkcs12 -nocerts -out apns-prod-key.pem -in apns_prod.p12
如果您想删除密码,请执行以下操作: (注意:导出/转换时使用'空白'密码,仍然确实设置了密码, 因此,如果您打算没有密码,您仍应执行以下操作) $ openssl rsa -in apns-prod-key.pem -out apns-prod-key-noenc.pem
最后,您需要将密钥和证书文件合并到我们将在连接到APNS时使用的apns-dev.pem文件中:
$ cat apns-prod-cert.pem apns-prod-key-noenc.pem> apns-prod.pem
答案 3 :(得分:-2)
尝试使用来自的PyAPNs
https://github.com/simonwhitaker/PyAPNs
或
pip install apns
请务必从iOS配置门户获取APNs证书和密钥,按照本指南安装并将其转换为.pem文件:
http://jainmarket.blogspot.com/2009/11/generate-apple-push-notification.html
这个图书馆非常紧张。
答案 4 :(得分:-3)
使用此代码:
#!/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()