django 的 APNS 问题

Posted

技术标签:

【中文标题】django 的 APNS 问题【英文标题】:APNS issue with django 【发布时间】:2014-12-02 05:05:16 【问题描述】:

我正在使用以下项目在我的项目中启用 APNS:

https://github.com/stephenmuss/django-ios-notifications

我可以在我的生产应用程序上发送和接收推送通知,但沙盒 apns 存在我无法解决的奇怪问题。它一直没有连接到推送服务。当我在 APNServiceFeedbackService 类上手动执行 _connect() 时,出现以下错误:

  File "/Users/MyUser/git/prod/django/ios_notifications/models.py", line 56, in _connect
    self.connection.do_handshake()
Error: [('SSL routines', 'SSL3_READ_BYTES', 'sslv3 alert handshake failure')]

我多次尝试重新创建 APN 证书并不断收到相同的错误。我还有什么遗漏的吗?

我正在使用端点 gateway.push.apple.comgateway.sandbox.push.apple.com 连接到服务。还有什么我应该调查的吗?我已阅读以下内容:

Apns php error "Failed to connect to APNS: 110 Connection timed out."

Converting PKCS#12 certificate into PEM using OpenSSL

Error Using PHP for iPhone APNS

【问题讨论】:

你找到答案了吗?你如何使用 TLS 推送通知? 当你连接到苹果的服务器时,你可以选择使用的上下文。查看我上面使用的项目以获得更多指导。该项目有效并且已准备好生产。 【参考方案1】:

我曾使用 python-django 开发过 APN,为此您需要 Apple 提供的三样东西 URL、PORTCertificate 用于身份验证。

views.py

import socket, ssl, json, struct

theCertfile = '/tmp/abc.cert'      ## absolute path where certificate file is placed.
ios_url = 'gateway.push.apple.com'
ios_port = 2195
deviceToken = '3234t54tgwg34g'    ## ios device token to which you want to send notification

def ios_push(msg, theCertfile, ios_url, ios_port, deviceToken):

    thePayLoad = 
               'aps': 
                    'alert':msg,
                    'sound':'default',
                    'badge':0,
                    ,
             

    theHost = ( ios_url, ios_port )
    data = json.dumps( thePayLoad )

    deviceToken = deviceToken.replace(' ','')
    byteToken = deviceToken.decode('hex') # Python 2

    theFormat = '!BH32sH%ds' % len(data)
    theNotification = struct.pack( theFormat, 0, 32, byteToken, len(data), data )

    # Create our connection using the certfile saved locally
    ssl_sock = ssl.wrap_socket( socket.socket( socket.AF_INET, socket.SOCK_STREAM ), certfile = theCertfile )
    ssl_sock.connect( theHost )

    # Write out our data
    ssl_sock.write( theNotification )

    # Close the connection -- apple would prefer that we keep
    # a connection open and push data as needed.
    ssl_sock.close()

希望这对你有用。

【讨论】:

此代码有效,但不是答案。原因是为了开发你现在必须使用TLS 而不是SSL3SSL3 仍在生产中工作,但将在不久的将来被删除。【参考方案2】:

原来 Apple 在开发中将 ssl 上下文从 SSL3 更改为 TLSv1。他们最终会在生产中执行此操作(不确定何时)。以下链接显示了我的拉取请求,该请求已被上述项目接受:

https://github.com/stephenmuss/django-ios-notifications/commit/879d589c032b935ab2921b099fd3286440bc174e

基本上,如果您使用的是 python 或其他语言中的类似内容,请使用 OpenSSL.SSL.TLSv1_METHOD

虽然OpenSSL.SSL.SSLv3_METHOD 可以在生产中使用,但在不久的将来可能无法使用。 OpenSSL.SSL.TLSv1_METHOD 从事生产和开发工作。

更新

由于 poodle 漏洞,Apple 将于 2014 年 10 月 29 日在生产中删除 SSL 3.0 支持。

https://developer.apple.com/news/?id=10222014a

【讨论】:

对于那些使用 apns-client 的人:目前有一个开放的拉取请求来解决这个问题bitbucket.org/sardarnl/apns-client/pull-request/10/…

以上是关于django 的 APNS 问题的主要内容,如果未能解决你的问题,请参考以下文章

Django APNS 和 Phonegap 建议

APNS生产证书问题

我可以在推送通知中使用官方 apns(或简易 apns)吗?

apns-csharp 证书问题

ios APNS 问题 xcode 6.4

从 APNS 收到的设备令牌的生命周期