25 - Current User / Me
เป้าหมายของบท
Section titled “เป้าหมายของบท”บทนี้จะเพิ่ม endpoint:
GET /api/v1/auth/meหลังจบบทนี้ผู้อ่านควรเข้าใจ:
/meใช้ทำอะไร- Spring Security อ่าน subject จาก JWT อย่างไร
- ใช้
Authenticationใน controller อย่างไร - ดึง user ปัจจุบันจาก email ใน token ได้อย่างไร
- ทำไม
/meต้องเป็น protected endpoint
ทำไมต้องมี /me
Section titled “ทำไมต้องมี /me”หลัง frontend login แล้วได้ token frontend มักต้องรู้ว่า token นี้เป็นของใคร เช่น:
- แสดงชื่อผู้ใช้บน navbar
- เช็ก role เพื่อแสดงเมนู admin
- refresh หน้าแล้วยังรู้ว่า user เป็นใคร
- ตรวจว่า token ยังใช้ได้หรือไม่
endpoint /me จึงเป็น endpoint มาตรฐานในระบบที่ใช้ token
Authentication มาจากไหน
Section titled “Authentication มาจากไหน”เมื่อ client ส่ง:
Authorization: Bearer <token>Spring Security Resource Server จะตรวจ token ถ้าถูกต้องจะสร้าง Authentication ให้ request นั้น
ค่า authentication.getName() จะมาจาก claim sub ของ JWT ซึ่งในหนังสือนี้เราใช้ email เป็น subject
เพิ่ม endpoint ใน AuthController
Section titled “เพิ่ม endpoint ใน AuthController”เปิด AuthController แล้วเพิ่ม:
@GetMapping("/me")public ApiResponse<UserResponse> me(Authentication authentication) { String email = authentication.getName(); return ApiResponse.ok("Current user found", authService.getCurrentUser(email));}import ที่ต้องใช้:
import org.springframework.security.core.Authentication;import org.springframework.web.bind.annotation.GetMapping;เพิ่ม method ใน AuthService
Section titled “เพิ่ม method ใน AuthService”public UserResponse getCurrentUser(String email) { User user = userRepository.findByEmail(email) .orElseThrow(() -> new BadCredentialsException("Invalid token"));
return toResponse(user);}ถ้า token ถูกต้องแต่หา user ใน database ไม่เจอ อาจเป็นเพราะ user ถูกลบไปแล้ว ในบทนี้ตอบแบบกลาง ๆ ว่า token ใช้ไม่ได้
ทดสอบแบบไม่มี token
Section titled “ทดสอบแบบไม่มี token”GET /api/v1/auth/meควรได้:
401 Unauthorizedทดสอบแบบมี token
Section titled “ทดสอบแบบมี token”GET /api/v1/auth/meAuthorization: Bearer eyJ...response:
{ "success": true, "message": "Current user found", "data": { "id": 1, "username": "john", "email": "john@example.com", "role": "USER", "status": "ACTIVE" }}ถ้า user ถูก inactive ควรทำอย่างไร
Section titled “ถ้า user ถูก inactive ควรทำอย่างไร”ในบทนี้ /me ยังดึงข้อมูล user ปกติ
ในงานจริงควรคิดต่อว่า user ที่ INACTIVE ควรใช้ token เดิมต่อได้ไหม ส่วนมากควรปฏิเสธ request หรือบังคับ login ใหม่หลังเปลี่ยนสถานะ
เรื่องนี้จะกลับมาอีกครั้งในภาค Admin System
แบบฝึกหัดท้ายบท
Section titled “แบบฝึกหัดท้ายบท”- เพิ่ม endpoint
/api/v1/auth/me - login เพื่อรับ token
- เรียก
/meโดยไม่ใส่ token - เรียก
/meโดยใส่ token - ลองแก้ token หนึ่งตัวอักษรแล้วเรียกใหม่