Zalo refresh token: Cách làm mới access token an toàn

Zalo API sử dụng access token để xác nhận ứng dụng có quyền truy cập tài nguyên được bảo vệ. Tuy nhiên, access token chỉ tồn tại trong thời gian giới hạn nên hệ thống không thể lưu một token rồi dùng mãi mãi. Zalo refresh token giúp ứng dụng xin access token mới mà không yêu cầu quản trị viên hoặc người dùng thực hiện lại toàn bộ quy trình cấp quyền.

Trong môi trường production, lập trình viên còn phải xử lý xoay vòng token, ngăn chạy đồng thời, lưu dữ liệu an toàn và chuẩn bị phương án cấp quyền lại. Hướng dẫn này tập trung vào Zalo Official Account API.

Zalo refresh token là gì và khác access token thế nào?

Access token là mã ứng dụng dùng khi gọi Zalo API. Máy chủ Zalo kiểm tra token, phạm vi quyền và trạng thái ủy quyền trước khi trả dữ liệu. Thời hạn ngắn giúp giới hạn rủi ro nếu token bị lộ.

Zalo refresh token không được dùng trực tiếp để gọi API nghiệp vụ như gửi tin nhắn, đọc thông tin OA hoặc truy vấn người dùng. Nó chỉ được gửi tới máy chủ OAuth để đổi lấy một bộ token mới. Phản hồi thường gồm access token mới, refresh token mới và thời hạn.

Thành phần Mục đích Cách quản lý
Access token Gọi Zalo API Lưu cache và thay mới trước khi hết hạn
Refresh token Xin bộ token mới Bảo mật cao, cập nhật sau mỗi lần refresh
App Secret Xác thực ứng dụng Chỉ lưu phía máy chủ

Với OA Access Token, tài liệu Zalo hiện mô tả access token có hiệu lực khoảng 25 giờ, còn refresh token có hiệu lực khoảng 3 tháng. Refresh token của luồng này chỉ được dùng một lần. Khi đổi token thành công, hệ thống phải lưu refresh token mới trong phản hồi và ngừng sử dụng giá trị cũ.

Cần phân biệt OA Access Token với User Access Token vì hai loại phục vụ nhóm API khác nhau. Không áp dụng ví dụ OA API cho Social API nếu chưa kiểm tra đúng loại token.

Luồng làm mới access token của Zalo

Zalo refresh token - Zalo refresh token là gì và khác access token thế nào?
Zalo refresh token – Zalo refresh token là gì và khác access token thế nào?

Quy trình bắt đầu khi ứng dụng dùng authorization code để lấy bộ token đầu tiên và lưu trong kho bảo mật. Hệ thống duy trì quyền truy cập cho đến khi refresh token hết hạn hoặc bị thu hồi.

Các bước xử lý tiêu chuẩn

  1. Đọc access token, refresh token và thời điểm hết hạn từ cơ sở dữ liệu.
  2. Kiểm tra access token còn đủ thời gian sử dụng hay không.
  3. Nếu token sắp hết hạn, khóa bản ghi để chỉ một tiến trình được refresh.
  4. Gửi refresh token hiện tại đến endpoint OAuth của Zalo.
  5. Kiểm tra mã HTTP và dữ liệu phản hồi.
  6. Ghi đồng thời access token mới, refresh token mới và thời điểm hết hạn.
  7. Mở khóa rồi tiếp tục gọi API.

Nên refresh trước khi hết hạn 10 đến 30 phút để tránh lỗi do lệch đồng hồ, độ trễ mạng hoặc tác vụ kéo dài.

Không refresh trước mọi lần gọi API. Hãy lưu expires_at, kiểm tra tại lớp quản lý token dùng chung và chỉ làm mới khi cần.

Vì sao phải xoay vòng refresh token?

Sau một lần refresh thành công, refresh token đã gửi đi không còn là giá trị nên tiếp tục sử dụng. Phản hồi mới phải được lưu theo một giao dịch nguyên tử.

Giả sử hai worker cùng đọc một refresh token. Worker A đổi thành công và nhận token mới. Worker B vẫn gửi giá trị cũ nên có thể thất bại. Nếu B ghi đè dữ liệu của A, hệ thống sẽ mất chuỗi token hợp lệ. Vì vậy, cần dùng khóa phân tán, khóa hàng trong cơ sở dữ liệu hoặc cơ chế kiểm tra phiên bản trước khi cập nhật.

Cách gọi API làm mới token Zalo OA

Zalo refresh token - Vì sao phải xoay vòng refresh token?
Zalo refresh token – Vì sao phải xoay vòng refresh token?

Với Zalo OA OpenAPI, ứng dụng gửi yêu cầu POST đến endpoint OAuth dành cho OA. App Secret được đặt trong header secret_key, còn app_id, grant_typerefresh_token được gửi theo định dạng form URL encoded.

Ví dụ cURL:

curl –request POST
–url ‘https://oauth.zaloapp.com/v4/oa/access_token’
–header ‘Content-Type: application/x-www-form-urlencoded’
–header ‘secret_key: YOUR_APP_SECRET’
–data-urlencode ‘app_id=YOUR_APP_ID’
–data-urlencode ‘grant_type=refresh_token’
–data-urlencode ‘refresh_token=YOUR_CURRENT_REFRESH_TOKEN’

Các giá trị minh họa phải được thay bằng cấu hình thật. Không ghi App Secret hoặc token trực tiếp trong mã nguồn, ảnh chụp màn hình, log hay công cụ kiểm thử công khai.

Phản hồi thành công thường có cấu trúc tương tự:

{
“access_token”: “NEW_ACCESS_TOKEN”,
“refresh_token”: “NEW_REFRESH_TOKEN”,
“expires_in”: “90000”
}

Ứng dụng phải kiểm tra từng trường. expires_in là số giây token còn hiệu lực; có thể tính expires_at = thời_gian_hiện_tại + expires_in rồi áp dụng khoảng đệm.

Ví dụ Node.js

async function refreshZaloOAToken({
appId,
appSecret,
refreshToken
}) {
const body = new URLSearchParams({
app_id: appId,
grant_type: “refresh_token”,
refresh_token: refreshToken
});

const response = await fetch(
“https://oauth.zaloapp.com/v4/oa/access_token”,
{
method: “POST”,
headers: {
“Content-Type”: “application/x-www-form-urlencoded”,
“secret_key”: appSecret
},
body
}
);

const data = await response.json().catch(() => null);

if (!response.ok || !data?.access_token ||
!data?.refresh_token) {
throw new Error(
Zalo token refresh failed: ${response.status}
);
}

const expiresIn = Number(data.expires_in);

if (!Number.isFinite(expiresIn) || expiresIn <= 0) {
throw new Error(“Invalid expires_in from Zalo”);
}

return {
accessToken: data.access_token,
refreshToken: data.refresh_token,
expiresAt: new Date(Date.now() + expiresIn * 1000)
};
}

Trong dự án thật, hàm lưu token phải chạy cùng transaction hoặc khóa phân tán. Khi ghi log, không đưa toàn bộ phản hồi vào hệ thống giám sát vì dữ liệu có thể chứa token. Chỉ nên lưu mã HTTP, mã lỗi, OA ID và mã theo dõi nội bộ.

Thiết kế cơ chế tự động refresh token

Zalo refresh token - Ví dụ Node.js
Zalo refresh token – Ví dụ Node.js

Với hệ thống có nhiều máy chủ hoặc hàng đợi, nên xây dựng token manager dùng chung để đọc, đánh giá thời hạn, refresh và trả access token hợp lệ.

Làm mới chủ động và khi có lỗi

Có hai chiến lược phổ biến:

  • Làm mới chủ động: scheduler chạy định kỳ và refresh trước khi token hết hạn.
  • Làm mới phản ứng: khi API báo access token không hợp lệ, hệ thống refresh rồi thử lại một lần.

Nên kết hợp cả hai. Luồng chủ động giữ dịch vụ ổn định, còn luồng phản ứng xử lý trường hợp scheduler bị trễ, thời gian hết hạn lưu sai hoặc token bị thu hồi sớm. Khi retry, chỉ thử lại một lần sau khi có token mới để tránh vòng lặp vô hạn.

Dữ liệu cần lưu

Bảng token có thể gồm app_id, oa_id, access token đã mã hóa, refresh token đã mã hóa, access_expires_at, version, updated_atlast_refresh_status. Trường version hỗ trợ kiểm soát cập nhật đồng thời, còn trạng thái refresh giúp theo dõi vận hành.

Nếu quản lý nhiều OA, mỗi OA phải có bộ token riêng. Khóa làm mới nên đặt theo cặp App ID và OA ID.

Một quy trình an toàn là khóa bản ghi, kiểm tra lại expires_at, gọi OAuth nếu vẫn cần, cập nhật cả hai token, tăng version rồi mới trả access token cho worker. Nếu không muốn giữ transaction trong lúc gọi mạng, có thể dùng distributed lock có thời gian hết hạn.

Lưu trữ Zalo refresh token an toàn

Refresh token có tuổi thọ dài và có thể tạo access token mới, vì vậy cần được bảo vệ như thông tin đăng nhập quan trọng. Không lưu token ở localStorage, mã JavaScript phía trình duyệt, ứng dụng mobile không có vùng lưu trữ an toàn hoặc file cấu hình được commit lên Git.

Nên lưu token phía máy chủ trong secret manager, kho khóa hoặc cơ sở dữ liệu có mã hóa. Khóa giải mã phải được quản lý tách biệt khỏi dữ liệu. Tài khoản dịch vụ chỉ được cấp quyền đọc token cần thiết, còn thao tác xem bản rõ phải bị hạn chế và có audit log.

Các nguyên tắc quan trọng:

  • Luôn truyền token qua HTTPS.
  • Che token trong log, cảnh báo và công cụ giám sát.
  • Không gửi token qua email, chat nhóm hoặc ticket hỗ trợ.
  • Tách bí mật giữa development, staging và production.
  • Xoay App Secret khi nghi ngờ bị lộ.
  • Giới hạn quyền truy cập theo nguyên tắc tối thiểu.
  • Mã hóa cả dữ liệu sao lưu.

Trang quản trị chỉ nên hiển thị vài ký tự đầu và cuối; chức năng sao chép bí mật phải được phân quyền và ghi audit log.

Lỗi refresh token hết hạn và cách khắc phục

Lỗi thường đến từ các nguyên nhân: refresh token đã hết hạn, token đã được dùng một lần, App Secret không đúng, dữ liệu gửi sai định dạng, quyền ủy quyền bị thu hồi hoặc ứng dụng dùng nhầm token của môi trường khác.

Khi gặp lỗi, hãy kiểm tra endpoint và loại token trước. Sau đó xác minh app_id, header secret_key, grant_type=refresh_token và nội dung form. Tiếp theo, xem lịch sử refresh để biết token hiện tại đã được dùng chưa. Không nên liên tục gửi lại cùng một refresh token vì retry mù quáng không tạo ra token hợp lệ.

Nếu refresh token đã hết hạn hoặc bị thu hồi, ứng dụng không thể tự phục hồi bằng refresh flow. Quản trị viên hoặc người dùng phải thực hiện lại quy trình cấp quyền để lấy authorization code mới, sau đó đổi mã này thành bộ token mới. Hệ thống nên cảnh báo rõ OA nào cần cấp quyền lại và hướng dẫn đúng tài khoản quản trị thực hiện.

Để giảm sự cố, hãy cảnh báo trước khi token gần hết hạn, giám sát scheduler, lưu mã lỗi có chọn lọc và kiểm thử nhiều worker cùng refresh.

Zalo refresh token nên được xem là một chuỗi trạng thái liên tục, không phải giá trị cấu hình cố định. Mỗi lần làm mới thành công, hệ thống phải chuyển ngay sang refresh token mới. Logic OAuth nên được tách khỏi nghiệp vụ và có kiểm thử cho lỗi mạng, phản hồi thiếu trường, cập nhật đồng thời và token bị thu hồi tại zalo web.

Một cơ chế tốt cần bảo đảm ba mục tiêu: API luôn nhận access token hợp lệ, refresh token mới được lưu nguyên tử và bí mật không xuất hiện trong log. Khi xử lý đúng ba phần này, ứng dụng tích hợp Zalo API sẽ ổn định hơn, giảm thao tác thủ công và hạn chế gián đoạn dịch vụ.

Rate this post

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *