ฟังก์ชัน จดจำฉัน ด้วย JWT
This commit is contained in:
parent
f615e51c5c
commit
98fcaeba3f
@ -102,7 +102,7 @@ export default function LoginForm() {
|
||||
{/* Checkbox และ Link ลืมรหัสผ่าน */}
|
||||
<div className='flex justify-between items-center text-sm mt-6'>
|
||||
<label className="flex items-center space-x-2 text-gray-600">
|
||||
<input type="checkbox" className="checkbox checkbox-primary checkbox-sm" />
|
||||
<input type="checkbox" className="checkbox checkbox-primary checkbox-sm" {...register('remember_me')}/>
|
||||
<span>จดจำฉัน</span>
|
||||
</label>
|
||||
<Link to="/forgot-password">
|
||||
|
||||
@ -15,8 +15,18 @@ const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
|
||||
* แปลง Object ให้เป็นฟอร์มข้อมูล (x-www-form-urlencoded)
|
||||
*/
|
||||
const toFormUrlEncoded = (data) => {
|
||||
// วนซ้ำ key และ encode
|
||||
return Object.keys(data)
|
||||
.map(key => encodeURIComponent(key) + '=' + encodeURIComponent(data[key]))
|
||||
.map(key => {
|
||||
let value = data[key];
|
||||
// รับค่า remember_me (boolean) มาแปลงเป็น String 'true'
|
||||
if (value === true) {
|
||||
value = 'true';
|
||||
} else if (value === false) {
|
||||
value = 'false'; // หรือจะส่งเฉพาะเมื่อเป็น true ก็ได้
|
||||
}
|
||||
return encodeURIComponent(key) + '=' + encodeURIComponent(value);
|
||||
})
|
||||
.join('&');
|
||||
};
|
||||
|
||||
@ -121,6 +131,8 @@ export const useLoginMutation = () => {
|
||||
|
||||
// 1. จัดการ Token และ User Data
|
||||
localStorage.setItem('token', data.access_token);
|
||||
// บันทึก Refresh Token แยกต่างหาก
|
||||
localStorage.setItem('refresh_token', data.refresh_token);
|
||||
localStorage.setItem('user', JSON.stringify(data.user));
|
||||
localStorage.setItem('role', data.role); // บันทึก Role ที่ถูกต้อง
|
||||
|
||||
@ -251,3 +263,21 @@ export const useConfirmPasswordReset = () => {
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* ฟังก์ชันสำหรับเรียก API เพื่อต่ออายุ Access Token ด้วย Refresh Token
|
||||
*/
|
||||
export const refreshAccessToken = async () => {
|
||||
const refresh = localStorage.getItem('refresh_token'); // เก็บ Refresh Token แยกต่างหาก
|
||||
|
||||
if (!refresh) {
|
||||
throw new Error("Refresh token not found.");
|
||||
}
|
||||
|
||||
const response = await axios.post(`${API_BASE_URL}/api/v1/auth/jwt/refresh/`, {
|
||||
refresh: refresh,
|
||||
});
|
||||
|
||||
// คืนค่า Access Token ใหม่
|
||||
return response.data.access;
|
||||
};
|
||||
@ -1,6 +1,7 @@
|
||||
import axios from 'axios';
|
||||
import { getStore } from '../app/store';
|
||||
import { logout } from '../features/auth/authSlice';
|
||||
import { refreshAccessToken } from './authApi';
|
||||
|
||||
// REGEX ตรวจจับตัวเลขที่ใหญ่เกิน 15 หลัก (ซึ่งเกินขีดจำกัดความปลอดภัยของ JS)
|
||||
const bigIntRegex = /"id":(\d{15,})/g;
|
||||
@ -55,8 +56,37 @@ axiosClient.interceptors.request.use(
|
||||
|
||||
axiosClient.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
async (error) => {
|
||||
const status = error.response ? error.response.status : null;
|
||||
const originalRequest = error.config;
|
||||
|
||||
// ถ้าเป็น 401 และ Request นั้นยังไม่ถูกลอง Refresh
|
||||
if (status === 401 && !originalRequest._retry) {
|
||||
|
||||
originalRequest._retry = true; // ตั้ง Flag ว่ากำลังจะลอง Refresh
|
||||
|
||||
const storeInstance = getStore();
|
||||
|
||||
try {
|
||||
// 1. เรียกฟังก์ชัน Refresh Token
|
||||
const newAccessToken = await refreshAccessToken();
|
||||
|
||||
// 2. บันทึก Access Token ใหม่
|
||||
localStorage.setItem('token', newAccessToken);
|
||||
|
||||
// 3. อัปเดต Header ของ Request เดิม
|
||||
originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
|
||||
|
||||
// 4. ลองเรียก Request เดิมซ้ำอีกครั้ง
|
||||
return axiosClient(originalRequest);
|
||||
|
||||
} catch (refreshError) {
|
||||
// หาก Refresh Token ล้มเหลว (หมดอายุ 30 วันแล้ว)
|
||||
console.error("JWT Refresh Failed. Logging out.", refreshError);
|
||||
storeInstance.dispatch(logout()); // บังคับ Logout
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
// ถ้าได้รับ 401 หรือ 403 (Token หมดอายุ/ไม่มีสิทธิ์)
|
||||
if (status === 401 || status === 403) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user