Сервер APNS отвечает со статусом 8-недопустимый токен, но устройства регистрируются правильно

#php #apple-push-notifications #passbook #coupon #wallet

#php #apple-push-уведомления #сберкнижка #купон #кошелек

Вопрос:

Я внедряю функциональность сберкнижки для своего приложения для iOS. Я использую php в качестве языка на стороне сервера для генерации pass и распространения среди устройств. Проходы успешно установлены на устройстве, и я также могу обновить проход вручную, используя pull для referesh. Когда я пытаюсь автоматически обновить pass со стороны сервера, я получаю ответ со статусом 8-недопустимый токен с сообщением «Идентификатор — это rowID (индекс) в базе данных, который вызвал проблему. Apple отключит вас ….. «. Я не понимаю, почему это происходит. Устройства регистрируются правильно, и другие конечные точки также работают нормально. Если передача была неправильной с самого начала, она не должна быть установлена на устройстве. Я подписал пропуск, используя тот же сертификат идентификатора типа пропуска, который я использую для отправки push-уведомлений. Я также проверил свои сертификаты, используя эту команду, указанную здесь.

     $ openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert YourSSLCertAndPrivateKey.pem -debug -showcerts -CAfile server-ca-cert.pem  
  

Я проверил его как для изолированной среды, так и для производства, и он не показывает никакой ошибки.
Я использую рабочий URL для отправки push-уведомления для обновления pass; Вот мой код для отправки push;

         $apnsHost = 'gateway.push.apple.com';  
        $apnsPort = 2195;  
        $apnsCert = base_path().'/path/to/ptypeidcert.pem';//converted using ssl from passtypeid.p12 certificated  
        $push_token = $token;  
        $passIdentify = 'pass.myidentifier.coupon';  
        $payload = '{}';  
        $msg = chr(0) . pack('n', 32) . pack('H*', $push_token) . pack('n', strlen($payload)) . $payload . pack('n', strlen($passIdentify)) . $passIdentify;  

        $streamContext = stream_context_create();  

        stream_context_set_option($streamContext, 'ssl', 'cafile', base_path().'/path/to/entrust_2048_ca.cer');  
        stream_context_set_option($streamContext, 'ssl', 'local_cert', $apnsCert);  
        stream_context_set_option($streamContext, 'ssl', 'passphrase', 'export_password');  

        $apns = stream_socket_client('ssl://' . $apnsHost . ':' . $apnsPort, $error, $errorString, 2, STREAM_CLIENT_CONNECT, $streamContext);  

        fwrite($apns, $msg);  
        PushNotifications::checkAppleErrorResponse($apns);// Just created a class to read response from apn server  
        @socket_close($apns);  
        fclose($apns);  
  

Любая помощь в дальнейшей отладке была бы действительно оценена. Что-нибудь для отладки моих сертификатов?
Примечание: Мои конечные точки API обслуживаются по протоколу http только для целей тестирования, я обновлю их до протокола https. Я включил службы HTTP на устройстве для установки pass в passbook.

============ ОБНОВИТЬ ============= Вот шаги для генерации моих сертификатов.

  1. Сначала я загрузил свой сертификат идентификатора типа Pass (.cer), используя запрос CSR с моим ключом.
  2. Затем экспортировал этот сертификат, используя keychain access на Mac, в .p12 расширение, необходимое для подписания купона во время создания. Этот купон успешно устанавливается на устройство.
  3. Затем я преобразовал это .p12 в .pem , используемый в приведенном выше коде для подключения push-сервера. Используя команду;

    openssl pkcs12 -in path.p12 -out newfile.pem

Если что-то не так с моей генерацией сертификата, пожалуйста, укажите.

Комментарии:

1. Кошелек использует только конечную точку APNS для производства. Sandbox выдаст вам ошибку ‘8’. Вы уверены, что получаете ошибки ‘8’ от рабочей конечной точки? Если это так, убедитесь, что вы правильно составляете и отправляете полезную нагрузку.

2. @PassKit как вы можете видеть, я использую $apnsHost = 'gateway.push.apple.com'; рабочую конечную точку для push-уведомлений. Мой сертификат PassTypeId такой же, какой я использовал для подписи пропуска, просто преобразован в .pem с помощью openssl в командной строке.

3. Попробуйте это $payload = json_encode(['aps'=>[]]); $msg = chr(0) . chr(0) . chr(32) . pack('H*', str_replace(' ', '', $push_token)) . chr(0) . chr(mb_strlen($payload)) . $payload;

4. @PassKit Я пытался воспользоваться вашим предложением, но не смог заставить его работать. Похоже, на устройстве ничего не отображается. Но ошибка с недействительным купоном исчезла.