#api#auth
API กลุ่ม /auth
กลุ่มนี้คือประตูเข้าระบบทั้งหมด: ล็อกอินกับฐาน Main ของ provider (ผู้ให้บริการ) แต่ละราย แล้วได้ access token + refresh token (JWT, ดู JWT session token และการเพิกถอน (JWT + revocation store) และ ขั้นตอน login / เลือกบริษัท / refresh / logout (Identity login flow)). ทุก endpoint ด้านล่างเป็น Go backend ตรง ๆ ที่ router.go:73-82 ไม่ผ่าน RequireRight และไม่มี envelope {ok,data} (ตอบ JSON ตรง ๆ ด้วย response.JSON). ภาพรวมวงจรคำขอดู api-overview.
สรุป endpoint
| method | path | auth | หน้าที่ | handler |
|---|---|---|---|---|
| POST | /auth/login |
public | ตรวจรหัสผ่านกับฐาน Main ของ provider แล้วหา company ที่เข้าได้ | identity/handler.go:76 |
| POST | /auth/select-company |
public (ใช้ preAuthToken) | แลก preAuthToken + companyCode เป็น session เต็ม | identity/handler.go:123 |
| POST | /auth/refresh |
public (ใช้ refreshToken) | หมุน (rotate) refresh token ออก session ใหม่ | identity/handler.go:206 |
| POST | /auth/logout |
public (ใช้ refreshToken) | เพิกถอน session ทั้ง access และ refresh | identity/handler.go:239 |
| GET | /auth/me |
Authorization: Bearer <token> |
โปรไฟล์ผู้ใช้ตาม session (ตรวจสดกับฐาน Main) | identity/handler.go:164 |
POST /auth/login
- Request:
{"provider":"<provider>","dataGroup":"<dataGroup>","username":"<user>","password":"<password>"} - Response 200 มีสองรูปแบบ:
- เข้าได้บริษัทเดียว:
{"session":{"accessToken":"<token>","refreshToken":"<token>"}} - เข้าได้หลายบริษัท:
{"preAuthToken":"<token>","companies":[{"code":"<companyCode>","name":"<ชื่อบริษัท>"}]}ต้องเรียก/auth/select-companyต่อ
- เข้าได้บริษัทเดียว:
- Errors (รูปแบบ
{"error":{"message":"..."}}จากresponse.Error): 400 body ไม่ใช่ JSON, 401 provider/dataGroup/username/password ไม่ถูก, 403 ไม่มี company ที่เข้าถึงได้ใน dataGroup นี้ - ตัวอย่าง:
POST /auth/login
{"provider":"<provider>","dataGroup":"<dataGroup>","username":"<user>","password":"<password>"}
POST /auth/select-company
- Request:
{"preAuthToken":"<token>","companyCode":"<companyCode>"} - Response 200:
{"accessToken":"<token>","refreshToken":"<token>"}(ไม่ห่อด้วยsession) - Errors: 400 body ผิด, 401 preAuthToken ไม่ถูกหรือหมดอายุ หรือ company เข้าไม่ได้
GET /auth/me
- Header:
Authorization: Bearer <accessToken>(middlewareAuth, middleware/auth.go:39-57) - Response 200:
{"username","displayName","level","provider","dataGroup","company":{"code","name"}} - Errors: 401 token ขาด/ผิด หรือ session ถูกเพิกถอนแล้ว (ตรวจสดกับฐาน Main ไม่ใช่แค่ decode)
POST /auth/refresh
- Request:
{"refreshToken":"<token>"} - Response 200:
{"accessToken","refreshToken"}ชุดใหม่ ตัวเก่าใช้ไม่ได้ทันที (rotate) - Errors: 400 body ผิด, 401 refresh token ผิด/หมดอายุ หรือสิทธิ์ถูกถอน
POST /auth/logout
- Request:
{"refreshToken":"<token>"} - Response: 204 ไม่มี body; access token ที่คู่กันใช้ไม่ได้ทันที (ใช้ session id ร่วมกัน)
- Errors: 400, 401
ขีดจำกัด
- ไม่มี
MaxBytesReaderใน identity handler (ดูเฉพาะ timeout รวม 60 วินาทีจากchimiddleware.Timeoutที่ router.go:64) และไม่พบ rate-limit middleware ในhttp/(grep แล้ว) - ค่า HTTP status มาจาก
apperr.Kindผ่านresponse.Error(ดู รูปแบบ error และ response ของ API (apperr + response helper))
ฝั่งหน้าเว็บ (Next.js proxy)
เบราว์เซอร์ไม่เรียก Go ตรง ๆ แต่เรียก /api/auth/* ของ Next แล้ว Next เรียก Go ต่อ (เก็บ token ใน session cookie ฝั่ง server, ดู เซสชันและการยืนยันตัวตนฝั่ง frontend (Auth session & tokens), เส้นทาง API ฝั่ง Next.js ที่ส่งต่อไป Go backend (API proxy routes)):
POST /api/auth/login(app/api/auth/login/route.ts:9): เรียก/auth/login(บรรทัด 46) แล้วถ้าเป็นโหมด admin จะเรียก/auth/select-company(90) และ/auth/me(123); โหมด user ต้องมี dataGroup, โหมด admin ต้อง level >= 9; บัญชีสาธิต (demo) ถูกบล็อกในโหมด admin ด้วย 403DEMO_ADMIN_FORBIDDENPOST /api/auth/logout(route.ts:10): เรียก/auth/logout(17)GET /api/auth/session(route.ts:6): อ่าน session จาก cookie ไม่ยิง Go; ไม่มี session = 401NO_SESSIONGET|POST /api/auth/databases(route.ts:28, 107): แสดงรายชื่อฐานของผู้ใช้และเลือกฐาน ผ่าน API Workspace — ล็อกอิน Google, เลือกฐานบริษัท, สมาชิก, สิทธิ์จอ, ผูก LINE (Admin workspace API) (workspace/databases,workspace/select-db) แล้ว/auth/select-company(208) และ/auth/me(241)GET|POST /api/auth/google(route.ts:44, 214): OAuth Google แล้วเรียกworkspace/google-login(152) ด้วย admin keyPOST /api/auth/change-password(route.ts:34): ตรวจรหัสเดิมด้วย/auth/login(77) แล้วPATCH /api/v1/admin/users(95) ด้วย admin key — ดู API คอนโซลผู้ดูแล /api/v1/admin — provider, user, database, main-query, menu-permissions (Admin console API)POST /api/auth/demo(route.ts:9): ปุ่ม Demo — Next ออก session สาธิตให้เองแล้วsetSession(ไม่ยิง/auth/loginของ Go)- ตัวช่วย
getValidAccessToken(src/lib/api-server.ts:555) ต่ออายุ token ล่วงหน้าเมื่อเหลือไม่ถึง 60 วินาที;fetchServiceWithAuthRetry(388) ลอง refresh แล้วเรียกซ้ำเมื่อเจอ 401
ที่มาในโค้ด
backend/internal/adapter/inbound/http/router.go:73-82(route table /auth)backend/internal/adapter/inbound/http/identity/handler.go:31-260(request/response struct และ 5 handler)backend/internal/adapter/inbound/http/middleware/auth.go:39-57frontend/src/app/api/auth/login/route.ts:9-130,logout/route.ts:10,databases/route.ts:28-250,google/route.ts:44-214,change-password/route.ts:34-111frontend/src/lib/api-server.ts:388,555