Device Token là một định danh duy nhất mà APNS gán cho mỗi thiết bị iOS để định tuyến thông báo push. Token được hệ thống tạo ra khi ứng dụng đăng ký nhận thông báo và phải được gửi đến máy chủ để gửi push đến thiết bị này. Theo Tài liệu nhà phát triển Apple, 2026, Device Token có thể thay đổi khi cài đặt lại ứng dụng, khôi phục thiết bị từ bản sao lưu hoặc cập nhật iOS, do đó máy chủ phải thường xuyên cập nhật token để đảm bảo việc gửi.
Những điểm chính
Device Token (token thiết bị) là một định danh duy nhất dưới dạng chuỗi hex mà APNS (Apple Push Notification Service) tạo ra cho mỗi ứng dụng trên một thiết bị iOS. Token là khóa mà máy chủ sử dụng để gửi thông báo push đến một thiết bị cụ thể. Nếu không có Device Token hợp lệ, máy chủ không thể gửi thông báo push — APNS từ chối yêu cầu với lỗi 400 BadRequest.
Device Token được tạo bởi hệ thống iOS khi ứng dụng lần đầu tiên liên hệ với APNS sau khi cài đặt. Quá trình tạo bao gồm việc liên kết mật mã với bundle ID của ứng dụng và định danh duy nhất của thiết bị (UID), sau đó APNS trả về cho ứng dụng một token 32 byte ở định dạng hex (64 ký tự). Token không cố định — hệ thống có thể tạo một token mới trong những điều kiện nhất định.
Khi máy chủ gửi một thông báo push, nó bao gồm Device Token trong yêu cầu HTTP/2 đến APNS. APNS xác thực token: nếu token thuộc về môi trường khác (sandbox thay vì production), đã hết hạn hoặc bị thu hồi, máy chủ Apple trả về lỗi 410 Gone hoặc 400 BadRequest. Chỉ sau khi xác thực token thành công, APNS mới bắt đầu gửi thông báo đến thiết bị.
Device Token không nên bị nhầm lẫn với IDFA (Identifier for Advertisers), IDFV (Identifier for Vendor) hoặc UID (Unique Device Identifier). IDFA và IDFV được sử dụng cho quảng cáo và phân tích, UID là số sê-ri phần cứng. Device Token tồn tại dành riêng cho thông báo push và không tiết lộ thông tin về người dùng hoặc thiết bị bên ngoài APNS.
| Định danh | Mục đích | Tính cố định |
|---|---|---|
| Device Token | Định tuyến thông báo push APNS | Có thể thay đổi |
| IDFA | Quảng cáo và theo dõi | Có thể được đặt lại bởi người dùng |
| IDFV | Định danh nhà cung cấp (phân tích) | Cố định cho ứng dụng cùng nhà phát triển |
| Bundle ID | Định danh ứng dụng duy nhất | Cố định |
Quá trình lấy Device Token bao gồm một số bước bắt buộc, từ việc yêu cầu quyền từ người dùng đến gửi token đến máy chủ. Mỗi bước đều quan trọng — bỏ qua bất kỳ bước nào sẽ dẫn đến không thể gửi thông báo push đến thiết bị.
Bước đầu tiên là ứng dụng yêu cầu người dùng cho phép gửi thông báo qua UNUserNotificationCenter.current().requestAuthorization. Người dùng có thể đồng ý, từ chối hoặc chọn các tùy chọn (alert, badge, sound). Nếu không có sự đồng ý rõ ràng của người dùng, hệ thống sẽ không cấp Device Token, ngay cả khi ứng dụng gọi registerForRemoteNotifications. Sau khi nhận được quyền, ứng dụng gọi UIApplication.shared.registerForRemoteNotifications(), bắt đầu quá trình đăng ký với APNS.
Sau khi đăng ký, APNS trả về token thông qua AppDelegate: application(_:didRegisterForRemoteNotificationsWithDeviceToken:). Một cuộc gọi thành công chứa một đối tượng Data với token, cần được chuyển đổi thành chuỗi hex để truyền đến máy chủ. Trong trường hợp lỗi, hệ thống gọi application(_:didFailToRegisterForRemoteNotificationsWithError:) với mô tả vấn đề: cấu hình chứng chỉ không đúng, mạng không khả dụng hoặc cấu hình dự án không đúng.
Sau khi nhận được token, ứng dụng nên ngay lập tức gửi nó đến máy chủ để lưu trữ trong cơ sở dữ liệu. Yêu cầu API bao gồm token, định danh thiết bị (để ánh xạ), môi trường (sandbox/production) và tùy chọn dữ liệu bổ sung: phiên bản OS, mô hình thiết bị, ngôn ngữ. Nên gửi lại token mỗi khi ứng dụng khởi động để máy chủ luôn có token cập nhật.
// Yêu cầu quyền và đăng ký với APNS
func registerForPushNotifications() {
UNUserNotificationCenter.current()
.requestAuthorization(options: [.alert, .sound, .badge]) {
[weak self] granted, error in
guard granted else {
print("Không được cấp quyền")
return
}
DispatchQueue.main.async {
UIApplication.shared
.registerForRemoteNotifications()
}
}
}
// Lấy Device Token từ APNS
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
let tokenString = deviceToken
.map { String(format: "%02.2hhx", $0) }
.joined()
print("Device Token: \(tokenString)")
// Gửi token đến máy chủ
PushTokenService.shared
.sendTokenToServer(tokenString) { success in
if success {
UserDefaults.standard.set(tokenString,
forKey: "lastDeviceToken")
}
}
}
Phía máy chủ của hệ thống push phải lưu trữ Device Token trong cơ sở dữ liệu, liên kết với người dùng và môi trường. Khi gửi thông báo, máy chủ tạo một yêu cầu đến APNS, bao gồm token trong URL và token JWT (hoặc chứng chỉ) để ủy quyền. Quản lý token đúng cách ảnh hưởng nghiêm trọng đến tỷ lệ gửi thông báo push.
Bảng token trên máy chủ nên chứa ít nhất: Device Token (duy nhất), ID người dùng, môi trường (sandbox/production), ngày cập nhật cuối cùng và trạng thái (hoạt động/không hoạt động). Nên thêm chỉ mục trên token để tìm kiếm nhanh khi gửi và trên người dùng để lấy danh sách tất cả thiết bị của một người dùng. Nhiều ứng dụng cho phép một người dùng có nhiều thiết bị — mỗi thiết bị có token riêng.
Để gửi thông báo push, máy chủ phải ủy quyền yêu cầu đến APNS theo hai cách. Dựa trên chứng chỉ sử dụng chứng chỉ SSL được tạo trong Apple Developer Console. Dựa trên token sử dụng JWT (JSON Web Token) với khóa .p8 có hiệu lực đến 30 ngày mà không cần gia hạn chứng chỉ. Ủy quyền dựa trên token được coi là hiện đại hơn và được Apple khuyên dùng cho các dự án mới.
Yêu cầu đến APNS bao gồm phương thức HTTP/2 POST, URL với đường dẫn /3/device/{device_token}, header ủy quyền và phần thân JSON với tải trọng. Header apns-topic phải chứa bundle ID của ứng dụng. apns-priority cho biết mức độ ưu tiên gửi (5 — ngay lập tức, 10 — tiết kiệm pin). apns-expiration đặt thời gian tính bằng giây kể từ kỷ nguyên mà APNS sẽ cố gắng gửi thông báo.
// Ví dụ gửi push trên Node.js qua APNS HTTP/2
const http2 = require('http2');
const client = http2.connect('https://api.push.apple.com');
const deviceToken = 'abcdef0123456789...';
const payload = JSON.stringify({
"aps": { "alert": "Hello!", "sound": "default" }
});
const req = client.request({
':method': 'POST',
':path': `/3/device/${deviceToken}`,
'apns-topic': 'com.example.app',
'apns-priority': '10',
'apns-expiration': '0',
'authorization': `bearer ${jwtToken}`
});
req.write(payload);
req.end();
req.on('response', (headers) => {
if (headers[':status'] === '200') {
console.log('Đã gửi push thành công');
}
});
Khi gửi thông báo push đến một số lượng lớn thiết bị, hãy sử dụng tính năng gửi hàng loạt với kiểm soát tốc độ. APNS khuyên không vượt quá 1500 yêu cầu mỗi giây cho mỗi kết nối. Nếu vượt quá giới hạn, máy chủ Apple trả về lỗi 429 Too Many Requests. Đối với các chiến dịch quy mô lớn, hãy sử dụng nhiều kết nối và phân phối tải đều trên các thiết bị.
Device Token không cố định và có thể thay đổi trong một số kịch bản, đòi hỏi cơ chế cập nhật trên máy chủ. Nếu máy chủ tiếp tục gửi push đến một token cũ, APNS trả về lỗi 410 Gone, cho biết token không còn hiệu lực cho môi trường đã cho.
Apple ghi lại một số kịch bản mà Device Token thay đổi: người dùng cài đặt lại ứng dụng, khôi phục thiết bị từ bản sao lưu iCloud, cài đặt phiên bản iOS mới hoặc đặt lại cài đặt mạng hoặc quyền riêng tư. Trong mỗi trường hợp, ứng dụng sẽ nhận một token mới từ APNS khi khởi động lần tiếp theo. Máy chủ phải cập nhật token trong cơ sở dữ liệu, xóa token cũ và lưu token mới.
Khi máy chủ gửi push đến một token cũ, APNS trả về HTTP 410 với header apns-unless-timestamp. Header này cho biết thời gian mà token trở nên không hợp lệ. Máy chủ phải ngay lập tức xóa hoặc vô hiệu hóa token này trong cơ sở dữ liệu để tránh gửi lại cho nó. Bỏ qua lỗi 410 sẽ lãng phí tài nguyên và giảm tỷ lệ gửi thành công.
Để giữ cơ sở dữ liệu token được cập nhật, nên chạy dọn dẹp định kỳ. Script dọn dẹp phân tích nhật ký APNS trong N ngày qua, tìm tất cả token nhận được lỗi 410 và vô hiệu hóa chúng trong cơ sở dữ liệu. Ngoài ra, các token không có hoạt động người dùng trong hơn 90 ngày có thể bị xóa — đây là các bản ghi vô ích chỉ làm tăng kích thước cơ sở dữ liệu.
Trước khi gửi hàng loạt thông báo push (bản tin, chiến dịch khuyến mại), nên xác thực trước các token. APNS không cung cấp API trực tiếp để xác thực hàng loạt token, do đó chiến lược được sử dụng là gửi một push thử với ưu tiên thấp và phân tích lỗi. Các token trả về lỗi 410 sẽ bị loại khỏi đợt gửi chính.
Hãy xem xét toàn bộ chu trình lấy Device Token trong Swift, bao gồm xử lý lỗi và gửi đến máy chủ. Mã bao gồm yêu cầu quyền, đăng ký với APNS, chuyển đổi Data thành chuỗi hex, xử lý lỗi và gửi token đến máy chủ của bạn với các lần thử lại khi thất bại.
import UIKit
import UserNotifications
final class PushNotificationManager: NSObject {
static let shared = PushNotificationManager()
private let apiClient = APIClient()
private var currentToken: String?
func register() {
UNUserNotificationCenter.current()
.requestAuthorization(
options: [.alert, .badge, .sound]) {
[weak self] granted, error in
guard granted else {
Analytics.log(
"Push permission denied")
return
}
DispatchQueue.main.async {
UIApplication.shared
.registerForRemoteNotifications()
}
}
}
func handleDeviceToken(_ tokenData: Data) {
let token = tokenData
.map { String(format: "%02.2hhx", $0) }
.joined()
guard token != currentToken else { return }
currentToken = token
sendTokenToServer(token)
}
func handleRegistrationError(_ error: Error) {
Analytics.log(
"Push registration failed: \(error)")
// Thử lại sau khi trễ khi có lỗi mạng
if let urlError = error as? URLError,
urlError.code == .notConnectedToInternet {
DispatchQueue.main.asyncAfter(
deadline: .now() + 10) { [weak self] in
self?.register()
}
}
}
private func sendTokenToServer(_ token: String) {
let body = PushTokenRequest(
token: token,
environment: Environment.current == .debug
? "sandbox" : "production",
osVersion: UIDevice.current.systemVersion,
locale: Locale.current.identifier
)
apiClient.sendToken(body) { [weak self] result in
if case .success = result {
self?.currentToken = token
}
}
}
}
Lỗi trong quá trình đăng ký APNS có thể do nhiều nguyên nhân. Phổ biến nhất bao gồm mạng không khả dụng, cấu hình chứng chỉ không đúng trong Xcode (ví dụ, tính năng Push Notifications bị tắt), sử dụng trình mô phỏng (không hỗ trợ push) hoặc hồ sơ cấp quyền không đúng. Trong môi trường production, điều quan trọng là ghi lại lỗi và nếu có thể, thử đăng ký lại khi ứng dụng khởi động lần tiếp theo.
Trình mô phỏng iOS không hỗ trợ nhận Device Token thực. Để kiểm tra đăng ký trên trình mô phỏng, hãy sử dụng kiểm tra kiến trúc i386: trong bản dựng debug, bạn có thể mô phỏng việc nhận token hoặc sử dụng kiểm thử UI với các đối tượng giả. Kiểm tra thông báo push thực tế luôn được thực hiện trên thiết bị thực tế được kết nối với Xcode.
Câu hỏi thường gặp
Có, Device Token có thể thay đổi khi cài đặt lại ứng dụng, khôi phục thiết bị từ bản sao lưu hoặc cập nhật iOS. Máy chủ phải xử lý các bản cập nhật token: khi nhận được token mới từ một thiết bị đã biết, hãy thay thế token cũ; khi xảy ra lỗi 410, hãy xóa token khỏi cơ sở dữ liệu.
Device Token là một chuỗi hex 32 byte gồm 64 ký tự viết thường (0–9, a–f). Ví dụ: “a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2”. Token được truyền dưới dạng Data từ APNS và được chuyển đổi thành chuỗi ở phía ứng dụng.
Token sandbox được cấp cho các ứng dụng được xây dựng với hồ sơ cấp quyền phát triển và chỉ hoạt động với api.sandbox.push.apple.com. Token production dành cho App Store và TestFlight và hoạt động với api.push.apple.com. Máy chủ phải phân biệt các môi trường và gửi push đến điểm cuối APNS thích hợp.
Lỗi 410 Gone có nghĩa là Device Token không hợp lệ. Máy chủ phải ngay lập tức xóa token này khỏi cơ sở dữ liệu và ngừng cố gắng gửi đến nó. Header apns-unless-timestamp trong phản hồi cho biết token đã ngừng hoạt động từ khi nào.
Kiểm tra phương thức ủy quyền application(_:didRegisterForRemoteNotificationsWithDeviceToken:) trong AppDelegate. Nếu phương thức được gọi, token đã được nhận. Sử dụng nhật ký gỡ lỗi hoặc OSLog để xuất token ra bảng điều khiển Xcode. Trên thiết bị thật, hãy xác nhận token đang được gửi đến máy chủ bằng Network Link Conditioner.
Tổng kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm