Khi tích hợp Zalo API hoặc hệ thống dùng OAuth 2.0, lập trình viên thường gặp access token và refresh token. Access token được gửi kèm yêu cầu gọi API, còn refresh token giúp ứng dụng xin access token mới khi mã hiện tại hết hạn. Hiểu đúng refresh token là gì giúp duy trì phiên kết nối ổn định mà không bắt người dùng đăng nhập lại liên tục. Nếu triển khai sai, ứng dụng có thể bị gián đoạn hoặc lộ thông tin xác thực.
Nội dung chính
Refresh token là gì và khác access token thế nào?
Refresh token là gì có thể hiểu là một chuỗi xác thực do máy chủ ủy quyền cấp cho ứng dụng, dùng để yêu cầu access token mới mà không cần người dùng thực hiện lại toàn bộ quá trình đăng nhập hoặc cấp quyền. Refresh token thường chỉ được gửi đến endpoint làm mới token, không dùng trực tiếp trong mỗi yêu cầu API nghiệp vụ.
Access token là mã ứng dụng sử dụng để truy cập tài nguyên được bảo vệ. Khi gọi API lấy dữ liệu, gửi thông tin hoặc thực hiện thao tác đã được cấp quyền, ứng dụng phải gửi access token theo định dạng nền tảng yêu cầu.
Sự khác biệt chính gồm:
- Access token dùng trực tiếp để gọi API.
- Refresh token dùng để xin access token mới.
- Access token thường có thời hạn ngắn hơn.
- Refresh token cần được bảo vệ nghiêm ngặt hơn.
- Refresh token chỉ nên được dùng tại backend đáng tin cậy.
Có thể hình dung access token giống thẻ ra vào có hiệu lực ngắn. Refresh token giống giấy tờ cho phép đổi sang thẻ mới. Giấy tờ này không nên đưa xuống trình duyệt, ứng dụng phía khách hoặc ghi vào log công khai.
Vì sao ứng dụng cần refresh token?

Nếu chỉ có access token, mỗi khi token hết hạn, người dùng có thể phải đăng nhập hoặc cấp quyền lại. Điều này gây gián đoạn, đặc biệt với hệ thống chạy nền như đồng bộ dữ liệu, chatbot, công cụ quản trị OA hoặc dịch vụ kết nối nhiều tài khoản.
Sau khi hiểu refresh token là gì, có thể thấy cơ chế này giải quyết hai yêu cầu cùng lúc. Access token cần sống ngắn để giảm thiệt hại khi bị lộ, nhưng ứng dụng vẫn cần duy trì kết nối đủ lâu để vận hành liên tục. Refresh token là cầu nối giữa hai yêu cầu đó.
Cơ chế này giảm số lần đăng nhập lại, hỗ trợ tác vụ nền, cho phép access token có thời hạn ngắn và giúp quản lý phiên theo từng tài khoản.
Refresh token không phải mã có hiệu lực vĩnh viễn. Nền tảng có thể đặt thời hạn, thu hồi token, yêu cầu xác thực lại hoặc cấp refresh token mới sau mỗi lần sử dụng. Vì vậy, hệ thống không được giả định một refresh token luôn hợp lệ.
Luồng phối hợp giữa refresh token và access token
Quy trình thường bắt đầu khi người dùng đăng nhập hoặc đồng ý cấp quyền. Máy chủ ủy quyền trả về access token, refresh token và thông tin như thời gian hết hạn. Backend lưu dữ liệu cần thiết và dùng access token để gọi Zalo API.
Nhận và lưu bộ token

Backend nên ghi nhận access token, refresh token, thời điểm cấp, thời điểm hết hạn dự kiến, phạm vi quyền và chủ sở hữu. Refresh token cần được mã hóa hoặc lưu trong hệ thống quản lý bí mật.
Metadata về thời hạn giúp ứng dụng chủ động làm mới và hỗ trợ điều tra lỗi.
Gọi API bằng access token
Trong vận hành bình thường, ứng dụng gửi access token theo đúng tài liệu API. Backend phải phân biệt lỗi token hết hạn với lỗi thiếu quyền, tham số sai, giới hạn tần suất hoặc lỗi hệ thống.
Không phải mọi phản hồi thất bại đều cần refresh; làm mới sai điều kiện có thể tạo vòng lặp.
Phát hiện token sắp hết hạn
Có thể làm mới chủ động dựa trên thời điểm hết hạn đã lưu hoặc chỉ làm mới khi API báo access token không còn hợp lệ. Cách an toàn là kết hợp cả hai: chủ động làm mới trước hạn nhưng vẫn xử lý trường hợp token bị thu hồi sớm hoặc đồng hồ máy chủ bị lệch.
Gửi yêu cầu làm mới
Backend gửi refresh token đến endpoint làm mới kèm các thông tin bắt buộc như app ID, secret, grant type hoặc tham số xác thực theo tài liệu nền tảng. Yêu cầu phải đi qua HTTPS và chỉ thực hiện từ môi trường máy chủ kiểm soát được.
Nếu thành công, máy chủ trả access token mới. Một số hệ thống còn trả refresh token mới. Khi đó, ứng dụng phải cập nhật cả hai giá trị cùng lúc, tránh trường hợp access token mới đi cùng refresh token cũ đã mất hiệu lực.
Thử lại yêu cầu ban đầu

Sau khi cập nhật token, ứng dụng có thể thử lại yêu cầu API trước đó một lần. Không nên retry vô hạn. Nếu lần thử lại vẫn lỗi xác thực, hệ thống cần đánh dấu phiên cần kiểm tra hoặc yêu cầu người dùng cấp quyền lại.
Đây là cơ chế quản lý vòng đời phiên truy cập, cần xử lý đồng bộ và retry cẩn thận.
Thời hạn, thu hồi và bảo mật token
Thời hạn cụ thể của access token và refresh token phụ thuộc nền tảng, loại ứng dụng, loại tài khoản và chính sách API tại thời điểm tích hợp. Lập trình viên không nên hard-code một con số dựa trên tài liệu cũ. Hãy ưu tiên giá trị thời hạn do API trả về và tài liệu kỹ thuật hiện hành.
Refresh token có thể mất hiệu lực khi:
- Hết thời hạn sử dụng.
- Người dùng thu hồi quyền đã cấp.
- Ứng dụng thay đổi thông tin bảo mật.
- Nền tảng phát hiện hoạt động bất thường.
- Token cũ đã được thay thế bằng token mới.
- Tài khoản bị khóa hoặc không còn đủ quyền.
Refresh token rotation là cơ chế cấp refresh token mới sau mỗi lần làm mới. Token cũ có thể bị vô hiệu ngay hoặc sau một khoảng chuyển tiếp. Khi áp dụng rotation, thao tác cập nhật dữ liệu phải có tính nguyên tử. Nếu ứng dụng nhận bộ token mới nhưng dừng trước khi lưu refresh token mới, phiên có thể mất khả năng làm mới ở lần tiếp theo.
Một lỗi phổ biến khác là nhiều tiến trình cùng phát hiện access token hết hạn và đồng thời gửi yêu cầu refresh. Backend nên dùng mutex, distributed lock hoặc trạng thái “refreshing” theo từng tài khoản để tại một thời điểm chỉ có một tiến trình làm mới.
Khi tìm hiểu refresh token là gì, cần xem đây là thông tin bí mật cấp cao. Kẻ tấn công có refresh token hợp lệ có thể xin access token mới và duy trì quyền truy cập trong thời gian dài.
Các nguyên tắc bảo mật nên áp dụng:
- Chỉ lưu refresh token ở backend.
- Không nhúng token trong JavaScript phía trình duyệt.
- Không truyền token trong URL.
- Mã hóa token khi lưu trong cơ sở dữ liệu.
- Giới hạn quyền truy cập theo nguyên tắc tối thiểu.
- Không ghi nguyên token vào log hoặc thông báo lỗi.
- Bảo vệ app secret và khóa mã hóa.
- Cảnh báo khi refresh thất bại nhiều lần.
- Có quy trình thu hồi và yêu cầu xác thực lại.
Trong hệ thống nhiều dịch vụ, token service riêng có thể lưu trữ, làm mới và cấp access token ngắn hạn, qua đó thu hẹp phạm vi rò rỉ.
Ví dụ xử lý làm mới token
Một token manager có thể hoạt động theo giả mã sau:
function getValidAccessToken(accountId):
tokenData = tokenStore.get(accountId)
if tokenData is missing:
throw ReauthorizationRequired
if accessToken is valid with safety buffer:
return tokenData.accessToken
acquire lock for accountId
tokenData = tokenStore.get(accountId)
if another process already refreshed:
release lock
return tokenData.accessToken
response = refreshTokenRequest(
refreshToken = tokenData.refreshToken,
clientCredentials = secureConfig
)
if response is successful:
tokenStore.updateAtomically(
accessToken = response.accessToken,
refreshToken = response.newRefreshToken
or tokenData.refreshToken,
expiresAt = response.expiresAt
)
release lock
return response.accessToken
mark reauthorization required
release lock
throw ReauthorizationRequired khám phá thêm tại web zalo.

Vương Minh – người dẫn dắt và đứng sau sự thành công của ZALO Web cùng với đội ngũ kĩ sư ưu tú nhất. Với khát vọng tạo ra một sản phẩm công nghệ “Make in Vietnam” đủ sức cạnh tranh sòng phẳng với các đối thủ quốc tế, ông Khải cùng các cộng sự tại Zalo Group đã không ngừng cải tiến để Zalo không chỉ là app nhắn tin mà còn là một hệ sinh thái làm việc đa nền tảng. Zalo Web chính là minh chứng cho triết lý đó: tinh gọn, tốc độ và thấu hiểu sâu sắc thói quen của người dùng Việt.
