2016-10-09 14 views
23

Apple gần đây đã thêm phương thức xác thực mới vào APNS (Apple Push Notification Authentication Key (Sandbox & Production)).Làm cách nào để gửi tin nhắn push của APN bằng APNs Auth Key và các công cụ CLI chuẩn?

enter image description here

Mấu chốt tải xuống là một tập tin .p8 với một khóa bí mật:

$ cat APNSAuthKey_3HHEB343FX.p8 
-----BEGIN PRIVATE KEY----- 
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBH...Already.Revoked...lHEjCX1v51W 
-----END PRIVATE KEY----- 

Tôi đang sử dụng các thông điệp APN bằng cách sử dụng phương pháp cũ - bổ sung chúng vào móc chìa khóa, yêu cầu cho một giấy chứng nhận và sử dụng OpenSSL để gửi tin nhắn đến gateway.production.push.apple.com:2195.

Làm cách nào để gửi thông báo đẩy bằng các công cụ CLI Linux chuẩn (OpenSSL, Python, v.v.) bằng định dạng mới?

Trả lời

32

Nếu bạn có curl với 2 hỗ trợ HTTP/và openssl với sự hỗ trợ ECDSA được cài đặt trên máy tính của bạn, bạn có thể sử dụng kịch bản sau đây để kiểm tra thông báo đẩy sử dụng một APN Auth chính:

#!/bin/bash 

deviceToken=b27371497b85611baf9052b4ccfb9641ab7fea1d01c91732149c99cc3ed9342f 

authKey="./APNSAuthKey_ABC1234DEF.p8" 
authKeyId=ABC1234DEF 
teamId=TEAM123456 
bundleId=com.example.myapp 
endpoint=https://api.development.push.apple.com 

read -r -d '' payload <<-'EOF' 
{ 
    "aps": { 
     "badge": 2, 
     "category": "mycategory", 
     "alert": { 
     "title": "my title", 
     "subtitle": "my subtitle", 
     "body": "my body text message" 
     } 
    }, 
    "custom": { 
     "mykey": "myvalue" 
    } 
} 
EOF 

# -------------------------------------------------------------------------- 

base64() { 
    openssl base64 -e -A | tr -- '+/' '-_' | tr -d = 
} 

sign() { 
    printf "$1"| openssl dgst -binary -sha256 -sign "$authKey" | base64 
} 

time=$(date +%s) 
header=$(printf '{ "alg": "ES256", "kid": "%s" }' "$authKeyId" | base64) 
claims=$(printf '{ "iss": "%s", "iat": %d }' "$teamId" "$time" | base64) 
jwt="$header.$claims.$(sign $header.$claims)" 

curl --verbose \ 
    --header "content-type: application/json" \ 
    --header "authorization: bearer $jwt" \ 
    --header "apns-topic: $bundleId" \ 
    --data "$payload" \ 
    $endpoint/3/device/$deviceToken 

LƯU Ý: Tôi sử dụng một biến thể nhỏ của tập lệnh này để thử nghiệm trên macOS với homebrew phiên bản của curl và openssl: http://thrysoee.dk/apns/

+0

Cảm ơn rất nhiều. Làm việc của nó – Sakthimuthiah

+1

@JessThrysoee "Biến thể nhỏ" của bạn hoạt động giống như ** CHAMP **. Cảm ơn bạn đã đăng công việc khó khăn của mình cho tất cả mọi người xem, đó là những người như bạn đã giữ cho cộng đồng được ép trái cây +1 – Jacksonkr

+1

Cảm ơn bạn vì tập lệnh rất hữu ích này. Trên máy Mac của tôi, tôi phải thêm tùy chọn "--with-nghttp2" để cài đặt curl với sự hỗ trợ http2 (như curl home-brew hiện không có hỗ trợ http2 theo mặc định): brew install curl - với-nghttp2. (hoặc như tôi đã đã curl cài đặt: brew cài đặt lại curl --with-nghttp2) Sau đó, trên lệnh curl trong kịch bản, tôi đã thêm các tùy chọn: --http2 và kịch bản hoạt động tốt. Cảm ơn bạn. –

8

Bạn có thể gửi thông báo đẩy bằng NODE JS bằng cách sử dụng Khóa xác thực thông báo đẩy của Apple (Sandbox & Sản xuất). Apple đã cung cấp hướng dẫn trong this link

Hướng dẫn này có tất cả các bước tạo Khóa xác thực thông báo đẩy của Apple và thiết lập máy chủ cục bộ để chạy mã JS của nút để gửi thông báo đẩy. Bạn có thể chạy mã trong máy cục bộ của mình và kiểm tra thông báo đẩy.

Hy vọng điều này sẽ hữu ích.

+0

Đây là trình tiết kiệm cuộc sống! Nó thật thanh lịch! –

0

Voilà trong Php nó trông như thế nào. Tập lệnh này trả lại mã trạng thái 200 ok cùng với mã thông báo được tạo.

// THE FINAL SCRIPT WITHOUT DEPENDENCIES!!! ...except curl with http2 
$device_token = "a0abd886etc..."; 
//echo $key; 
$kid  = "YOURKEYID"; 
$teamId = "YOURTEAMID"; 
$app_bundle_id = "your.app.bundle"; 
$base_url = "https://api.development.push.apple.com"; 

$header = ["alg" => "ES256", "kid" => $kid]; 
$header = base64_encode(json_encode($header)); 

$claim = ["iss" => $teamId, "iat" => time()]; 
$claim = base64_encode(json_encode($claim)); 

$token = $header.".".$claim; 
// key in same folder as the script 
$filename = "KeyFromApple.p8"; 
$pkey  = openssl_pkey_get_private("file://{$filename}"); 
$signature; 
openssl_sign($token, $signature, $pkey, 'sha256'); 
$sign = base64_encode($signature); 

$jws = $token.".".$sign; 

$message = '{"aps":{"alert":"You are welcome.","sound":"default"}}'; 

function sendHTTP2Push($curl, $base_url, $app_bundle_id, $message, $device_token, $jws) { 

    $url = "{$base_url}/3/device/{$device_token}"; 
    // headers 
    $headers = array(
     "apns-topic: {$app_bundle_id}", 
     'Authorization: bearer ' . $jws 
    ); 
    // other curl options 
    curl_setopt_array($curl, array(
     CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0, 
     CURLOPT_URL => $url, 
     CURLOPT_PORT => 443, 
     CURLOPT_HTTPHEADER => $headers, 
     CURLOPT_POST => TRUE, 
     CURLOPT_POSTFIELDS => $message, 
     CURLOPT_RETURNTRANSFER => TRUE, 
     CURLOPT_TIMEOUT => 30, 
     CURLOPT_SSL_VERIFYPEER => FALSE, 
     CURLOPT_HEADER => 1 
    )); 
    // go... 
    $result = curl_exec($curl); 
    if ($result === FALSE) { 
     throw new Exception("Curl failed: " . curl_error($curl)); 
    } 
    print_r($result."\n"); 
    // get response 
    $status = curl_getinfo($curl); 
    return $status; 
} 
// open connection 
$curl = curl_init(); 
sendHTTP2Push($curl, $base_url, $app_bundle_id, $message, $device_token, $jws); 
Các vấn đề liên quan