Chuột APICHUỘ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
| Method | Endpoint | Mục đích |
|---|---|---|
| GET | /oauth/authorize | Bắt đầu OAuth và chuyển tới login/signup. |
| POST | /oauth/token | Đổi authorization code thành access token. |
| GET | /userinfo | Lấy profile user bằng Bearer access token. |
| POST | /auth/register | Tạo tài khoản Chuột API. |
| POST | /auth/login | Đăng nhập username/password. |
| POST | /auth/logout | Xóa session trung tâm. |
| GET | /health | Kiể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
- direct_url là URL cuối cùng user được đưa về.
- redirect_uri là callback backend nhận code.
- Hai URL phải dùng HTTPS và khớp project tuyệt đối.
- client_secret/api_key chỉ được lưu ở backend.
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
- Username dài 5-30 ký tự.
- Username chỉ gồm a-z, 0-9 và dấu gạch dưới.
- Password dài 8-24 ký tự, có chữ thường và chữ hoa.
- Confirm password phải khớp.
- Username được kiểm tra realtime và backend kiểm tra lại.
- Dùng HTTPS, kiểm tra state và PKCE S256.
- Không log code, token, client secret hoặc API key.
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 dashboard10. 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:
authapi_session: session dashboard chính.authapi_oauth_session: session tạm cho OAuth của website bên ngoài.
Vì vậy các trường hợp sau đều an toàn:
- Dashboard Chuột API chưa đăng nhập.
- Dashboard đang đăng nhập tài khoản A.
- Website B yêu cầu user đăng nhập tài khoản B.
- Website C yêu cầu tạo tài khoản mới.
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.