เดิมทีแอปพลิเคชันของเราใช้ JWT (JSON Web Token) สำหรับการยืนยันตัวตน โดยจะแบ่งเป็น Access Token และ Refresh Token ซึ่งจะถูกส่งไปให้ฝั่ง Client เพื่อเก็บไว้ใน Local Storage ของเบราว์เซอร์
เพื่อเพิ่มความปลอดภัยและลดความเสี่ยงจากการโจมตีแบบ XSS (Cross-Site Scripting) เราได้เปลี่ยนระบบมาใช้ Session-based Authentication แทน โดยข้อมูล session จะถูกเก็บใน HTTP-only Cookie ซึ่งสามารถป้องกันไม่ให้สคริปต์ฝั่ง Client เข้าถึงได้โดยตรง ทำให้การจัดการ session มีความปลอดภัยมากขึ้น
สรุปการเปลี่ยนแปลงสำคัญ:
- เลิกใช้ JWT token ใน Local Storage
- ใช้ session-based authentication แทน
- ข้อมูล session ถูกเก็บใน HTTP-only Cookie
Registration
1. ลงทะเบียน Authentication Schema
ลงทะเบียน Schema session เพื่อให้ Policy-base เข้าถึง session และตรวจสอบสิทธิได้
builder.Services.AddAuth(builder.Configuration);2. ลงทะเบียน Cache
ลงทะเบียน Cache เพื่อจัดเก็บ Session ลง cache เพื่อ performance ในการตรวจสอบสิทธิ์ โดย defaul จะใช้ IDistributedCache ในการเรียกใช้และจัดเก็บ Session ซึ่งจะเก็บ Session ใน Memory instance ของ service ที่รันอยู่ แต่หาก เป็น microservices คุณสามารถใส่ connection redis เพื่อใช้ redis แทนเพื่อให้เหมาะสมกับสถานการณ์ของคุณ
// Program.cs
builder.Services.AddCache(builder.Configuration.GetSection("Redis")["ConnectionString"]);
// AddCache
public static IServiceCollection AddCache(this IServiceCollection services, string? connectionString)
{
if (string.IsNullOrEmpty(connectionString))
{
services.AddDistributedMemoryCache();
}
else
{
services.AddStackExchangeRedisCache(option =>
{
option.Configuration = connectionString;
});
}
return services;
}
3. ลงทะเบียน SessionService
ลงทะเบียน SessionService สำหรับจัดการ Session ของ user
builder.Services.AddScoped<SessionService>();การใช้งาน
จากนั้น inject SessionService เข้า class ที่ต้องการใช้งานผ่าน constructor
public class MyService
{
private readonly SessionService _session;
public MyService(SessionService session)
{
_session = session;
}
}Methods
| Name | Returns | Description |
CreateSession(String, SessionData, TimeSpan) | void | สร้าง session ใหม่และบันทึกลงใน cache |
GetSession(String) | SessionData? | ดึงข้อมูล session จาก sessionId |
RefreshSession(String, SessionData, TimeSpan) | void | อัปเดตข้อมูลและต่ออายุ session |
RemoveSession(String) | void | ลบ session ออกจาก cache |
RotateSession(String, SessionData, TimeSpan, TimeSpan) | string? | สร้าง session ใหม่และยกเลิกตัวเดิม |
Session Data
ข้อมูลที่เก็บใน session ประกอบด้วย
| Field | Description |
UserId | ID ของผู้ใช้ |
Role | รายการ role ของผู้ใช้ |
Permission | รายการ permission ในรูปแบบ roleId:functionId = view,edit |
ExpiresAt | เวลาหมดอายุของ session |
IsRotated | บอกว่า session นี้ถูก rotate ไปแล้วหรือยัง |