Chuột API

CHUỘT API / INTEGRATION GUIDE

NỀN TẢNG XÁC THỰC
NHANH CHÓNG.

Giải pháp xác thực dễ dàng tích hợp, hoàn toàn miễn phí. Tài liệu này mô tả đúng flow OAuth mà website test và các website bên thứ ba sử dụng.

1. Kiến trúc flow

Website tích hợp
  -> GET https://apiauth.pages.dev/api/v1/oauth/authorize
  -> https://apiauth.pages.dev/login?client_id=...
  -> https://apiauth.pages.dev/signup?client_id=... (nếu tạo tài khoản)
  -> callback URL của project với code + state
  -> backend đổi code tại /api/v1/oauth/token
  -> tạo session HttpOnly của website tích hợp
  -> redirect tới direct_url đã lưu trong project

client_id xác định project, không xác định user. User luôn được đăng nhập/tạo tài khoản trên Chuột API.

2. Base URL và endpoints

https://apiauth.pages.dev/api/v1
MethodEndpointMục đích
GET/oauth/authorizeBắt đầu OAuth và chuyển tới login/signup.
POST/oauth/tokenĐổi authorization code thành access token.
GET/userinfoLấy profile user bằng Bearer access token.
POST/auth/registerTạo tài khoản Chuột API.
POST/auth/loginĐăng nhập username/password.
POST/auth/logoutXóa session trung tâm.
GET/healthKiểm tra service.

3. Tạo project

Trong dashboard, đăng nhập rồi bấm Tạo project. Nhập tên, direct URL và callback URL.

AUTH_API_BASE_URL=https://apiauth.pages.dev/api/v1
AUTH_CLIENT_ID=client_...
AUTH_CLIENT_SECRET=cs_...
AUTH_REDIRECT_URI=https://your-site.com/auth/callback

4. Bắt đầu OAuth

Backend tạo state ngẫu nhiên và PKCE code_verifier, sau đó chuyển trình duyệt tới authorize.

const state = crypto.randomUUID();
const codeVerifier = crypto.randomUUID() + crypto.randomUUID();
const codeChallenge = base64Url(await sha256(codeVerifier));
saveSession({ state, codeVerifier });
const params = new URLSearchParams({
  client_id: process.env.AUTH_CLIENT_ID,
  redirect_uri: process.env.AUTH_REDIRECT_URI,
  response_type: "code",
  scope: "openid profile",
  state,
  code_challenge: codeChallenge,
  code_challenge_method: "S256",
  prompt: "login"
});
return Response.redirect(`https://apiauth.pages.dev/api/v1/oauth/authorize?${params}`, 302);

Chưa có session, Auth API sẽ mở:

https://apiauth.pages.dev/login?client_id=...&redirect_uri=...&state=...

Nút tạo tài khoản trên login sẽ chuyển tới `/signup?client_id=...` và giữ nguyên toàn bộ OAuth query.

5. Callback và token exchange

Callback backend nhận `code` và `state`. Kiểm tra state trước khi đổi code.

const tokenResponse = await fetch(
  "https://apiauth.pages.dev/api/v1/oauth/token",
  {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      grant_type: "authorization_code",
      client_id: process.env.AUTH_CLIENT_ID,
      client_secret: process.env.AUTH_CLIENT_SECRET,
      code: requestUrl.searchParams.get("code"),
      redirect_uri: process.env.AUTH_REDIRECT_URI,
      code_verifier: session.codeVerifier
    })
  }
);
const tokens = await tokenResponse.json();
{
  "access_token": "access_...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "openid profile",
  "direct_url": "https://your-site.com",
  "redirect_uri": "https://your-site.com/auth/callback"
}

6. Redirect đúng direct_url

Auth API lấy direct_url từ project tương ứng với client_id. Không hard-code URL trong Auth API.

await createHttpOnlySession(tokens.access_token);
return Response.redirect(tokens.direct_url, 302);

Project A và B có thể có direct URL khác nhau. Mỗi OAuth code cũng lưu direct URL theo project để token response trả đúng đích.

7. Lấy user profile

const response = await fetch(
  "https://apiauth.pages.dev/api/v1/userinfo",
  { headers: { Authorization: `Bearer ${accessToken}` } }
);
{
  "sub": "user.xxxxx",
  "preferred_username": "demo_user",
  "name": "Demo User"
}

Lưu access token trong session HttpOnly của website tích hợp, không lưu localStorage.

8. Tài khoản và bảo mật

9. Logout và revoke

POST https://apiauth.pages.dev/api/v1/auth/logout
POST https://apiauth.pages.dev/api/v1/oauth/revoke

Owner có thể revoke project trong dashboard. Project, API key, secret, OAuth code và access token liên quan sẽ bị xóa hoặc vô hiệu hóa.

← Quay lại dashboard

10. Cô lập tài khoản giữa web chính và website tích hợp

Website tích hợp không đăng nhập đè vào tài khoản đang mở trên dashboard Chuột API. Chuột API dùng hai session riêng:

Vì vậy các trường hợp sau đều an toàn:

Website bên ngoài nhận dữ liệu qua callback của chính project:

https://your-site.com/auth/callback?code=...&state=...

Backend website bên ngoài phải kiểm tra state, đổi code bằng client_secret, nhận access_token, gọi /userinfo và tự tạo session riêng. Chuột API không tự hiển thị user OAuth đó trên dashboard và không thay đổi account dashboard hiện tại.

Nếu website chỉ gọi /oauth/authorize nhưng không có callback backend để đổi code, website sẽ không nhận được profile user. Đây là bước bắt buộc của OAuth authorization-code flow.

← Quay lại dashboard