Nền tảng

Xác thực và kết nối

Token, kết nối, cách khách hàng nối vào, quyền truy cập.

API dùng OAuth 2.0. Có ba thứ bạn cần phân biệt.

Là gìSống bao lâuDùng ở đâu
client_id + client_secretdanh tính ứng dụng của bạn, mỗi môi trường một cặpcho đến khi bạn đổichỉ 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ối1 giờheader Authorization: Bearer
Refresh token ctas_rt_…để lấy access token mới90 ngày, gia hạn mỗi lần dùngchỉ 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_typeTham sốTrả về
client_credentialsclient_id, client_secrettoken ứ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_codecode, client_id, client_secrettoken kết nối + refresh token
authorization_codecode, code_verifier, redirect_uri, client_id, client_secrettoken kết nối + refresh token
refresh_tokenrefresh_token, client_id, client_secretcặ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ọiChuỗi mãCho phép
Thông tin tổ chứcorganization:readtổ chức, phòng ban, chức danh
Danh sách nhân sựmembers:readdanh 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:writetạo, cập nhật, cho nghỉ nhân sự; cấp mã kích hoạt
Lương cơ bảnmembers:salarythê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ệcattendance:readchấm công, lịch làm việc
Đơn nghỉ phépleave:readđọc đơn nghỉ
Duyệt đơn nghỉ phépleave:writeduyệt hoặc từ chối đơn nghỉ
Quy trình và biểu mẫuprocess:readbiểu mẫu, phân công, phiếu
Kích hoạt quy trìnhprocess:writekích hoạt lượt việc
Định danh bằng mã QRidentity:writetạo và theo dõi yêu cầu xác nhận bằng QR
Webhookwebhooks:managequản lý webhook bằng API
Phiếu lương đã chốtpayroll:readsố tổng của phiếu lương đã chốt và phiếu đang ở bước nào
Đánh dấu đã chi lươngpayroll: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.