API dùng OAuth 2.0. Có ba thứ bạn cần phân biệt.
| Là gì | Sống bao lâu | Dùng ở đâu | |
|---|---|---|---|
client_id + client_secret | danh tính ứng dụng của bạn, mỗi môi trường một cặp | cho đến khi bạn đổi | chỉ trong POST /oauth/token, chỉ từ máy chủ của bạn |
Access token ctas_at_… | vé gọi API, gắn với một kết nối | 1 giờ | header Authorization: Bearer |
Refresh token ctas_rt_… | để lấy access token mới | 90 ngày, gia hạn mỗi lần dùng | chỉ trong POST /oauth/token |
Đừng bao giờ đặt client_secret hay refresh token vào ứng dụng di động, mã chạy trên trình duyệt, hay commit vào git.
Giới hạn theo IP. Trong console, mỗi khoá có ô "Chỉ nhận yêu cầu từ IP". Khai địa chỉ hoặc dải CIDR của máy chủ bạn (IPv4 và IPv6), tối đa 20 dòng. Khi có danh sách, yêu cầu lấy token và mọi lời gọi API từ địa chỉ khác đều bị từ chối như một khoá sai. Để trống là nhận từ mọi nơi. Máy chủ của bạn đứng sau NAT hay đổi địa chỉ thì khai dải, đừng khai lẻ.
Kết nối là gì
Một kết nối (con_…) là sự cho phép của một tổ chức cho ứng dụng của bạn, với một tập quyền, ở một môi trường. Quản trị viên tổ chức cấp nó và có thể ngắt bất cứ lúc nào trong ứng dụng CTAS Work.
Mọi access token đọc dữ liệu tổ chức đều thuộc đúng một kết nối. Nếu phần mềm của bạn phục vụ nhiều khách hàng, hãy lưu một cặp token cho mỗi kết nối. Mỗi response kèm header X-CTAS-Connection và X-CTAS-Organization để bạn đối chiếu trước khi ghi vào dữ liệu của khách.
Tổ chức kết nối với ứng dụng của bạn thế nào
Cách A. Mã kết nối (khuyến nghị). Quản trị viên mở CTAS Work › tab Tổ chức › Ứng dụng đã kết nối › Kết nối ứng dụng, chọn ứng dụng của bạn (hoặc nhập mã ứng dụng 9 ký tự bạn đưa, dạng ADT-JWT-ORW), xem quyền, bấm Tạo mã kết nối. Họ nhận mã 12 ký tự dạng K7M2-QD4X-RN8P, hiệu lực 10 phút, dùng một lần. Phần mềm của bạn cho họ dán mã, máy chủ của bạn đổi mã lấy token.
Cách B. Uỷ quyền qua web. Phần mềm của bạn đưa quản trị viên tới:
https://developer.ctas.vn/oauth/authorize
?client_id=ctas_ci_live_…
&redirect_uri=https://app.example.com/ctas/callback
&scope=organization:read%20members:read
&state=…&code_challenge=…&code_challenge_method=S256
Họ đăng nhập, chọn tổ chức, đồng ý, và được đưa về redirect_uri?code=…&state=…. redirect_uri phải khớp đúng một địa chỉ đã đăng ký trong console. Đổi code lấy token với grant_type=authorization_code và code_verifier (PKCE).
Cả hai cách tạo ra cùng một kết nối. Bạn nhận sự kiện connection.created kèm organization_id.
Lấy token: POST /oauth/token
Nhận JSON hoặc form. Trả lời theo chuẩn OAuth 2.0.
grant_type | Tham số | Trả về |
|---|---|---|
client_credentials | client_id, client_secret | token ứng dụng, chỉ dùng cho /connections, /webhooks, /events. Với ứng dụng nội bộ: token của kết nối duy nhất |
urn:ctas:params:oauth:grant-type:connection_code | code, client_id, client_secret | token kết nối + refresh token |
authorization_code | code, code_verifier, redirect_uri, client_id, client_secret | token kết nối + refresh token |
refresh_token | refresh_token, client_id, client_secret | cặp token mới |
Lỗi có dạng {"error": "invalid_grant", "error_description": "…"} với HTTP 400 hoặc 401. Sai client_id hay client_secret luôn trả invalid_client.
Vòng đời token
gọi API → 401 TOKEN_EXPIRED
→ POST /oauth/token grant_type=refresh_token
→ 200: lưu CẢ HAI token mới, gọi lại
→ 400 invalid_grant: kết nối đã bị ngắt hoặc refresh token không còn dùng được
→ đánh dấu kết nối đứt, nhờ quản trị viên cấp mã kết nối mới
- Mỗi lần làm mới, bạn nhận refresh token mới và phải lưu nó. Refresh token cũ chỉ còn dùng được thêm 60 giây, để hai tiến trình cùng làm mới không đá nhau. Dùng lại refresh token cũ sau đó bị coi là rò rỉ: toàn bộ token của kết nối bị thu hồi và bạn nhận sự kiện
connection.compromised. Hãy khoá thao tác làm mới theo từng kết nối phía bạn. - Chủ động làm mới khi còn dưới 5 phút thay vì chờ 401.
POST /oauth/revoke{"token": "…"}khi khách hàng ngừng dùng phần mềm của bạn.POST /oauth/introspect{"token": "…"}trả trạng thái, quyền, kết nối và hạn của một token. Dùng khi cần gỡ lỗi.
Quyền truy cập (scope)
Mỗi quyền có tên gọi và một chuỗi mã. Tên gọi là thứ tổ chức khách hàng đọc trên màn hình đồng ý; chuỗi mã là thứ bạn truyền vào tham số scope.
| Tên gọi | Chuỗi mã | Cho phép |
|---|---|---|
| Thông tin tổ chức | organization:read | tổ chức, phòng ban, chức danh |
| Danh sách nhân sự | members:read | danh sách và hồ sơ cơ bản của nhân sự, không có lương hay giấy tờ |
| Quản lý nhân sự | members:write | tạo, cập nhật, cho nghỉ nhân sự; cấp mã kích hoạt |
| Lương cơ bản | members:salary | thêm lương cơ bản vào hồ sơ nhân sự |
| Ảnh đại diện nhân sự | members:avatar | đọc và thay ảnh đại diện của nhân sự |
| Chấm công và lịch làm việc | attendance:read | chấm công, lịch làm việc |
| Đơn nghỉ phép | leave:read | đọc đơn nghỉ |
| Duyệt đơn nghỉ phép | leave:write | duyệt hoặc từ chối đơn nghỉ |
| Quy trình và biểu mẫu | process:read | biểu mẫu, phân công, phiếu |
| Kích hoạt quy trình | process:write | kích hoạt lượt việc |
| Định danh bằng mã QR | identity:write | tạo và theo dõi yêu cầu xác nhận bằng QR |
| Webhook | webhooks:manage | quản lý webhook bằng API |
| Phiếu lương đã chốt | payroll:read | số tổng của phiếu lương đã chốt và phiếu đang ở bước nào |
| Đánh dấu đã chi lương | payroll:write | đánh dấu đã chi cho phiếu đã được duyệt |
Ứng dụng xin một tập quyền khi tạo. Tổ chức cấp đúng tập đó khi kết nối. Token có thể xin ít hơn, không thể nhiều hơn.
Mọi chỗ API trả về quyền — danh mục, màn hình đồng ý, thông tin kết nối — đều kèm name (tên gọi), label (một câu giải thích) và access (read hay write) bên cạnh key. Hãy hiển thị name; đừng in key cho người không viết mã đọc.
CTAS Developer