Add: api auth handeling

This commit is contained in:
Aroy-Art 2025-02-26 20:01:20 +01:00
parent 6cac4f0683
commit 10a3c457e9
Signed by: Aroy
GPG key ID: 583642324A1D2070

View file

@ -0,0 +1,107 @@
import axios from "axios";
const API_URL = "/api";
const apiInstance = axios.create({
baseURL: API_URL,
headers: {
"Content-Type": "application/json",
},
});
// Helper function to refresh tokens
const refreshAccessToken = async () => {
try {
const refreshToken = localStorage.getItem("refresh_token");
if (!refreshToken) throw new Error("No refresh token available");
const response = await axios.post(`${API_URL}/auth/token/refresh/`, {
refresh: refreshToken,
});
const newAccessToken = response.data.access;
const newRefreshToken = response.data.refresh || refreshToken; // Update if rotated
localStorage.setItem("access_token", newAccessToken);
localStorage.setItem("refresh_token", newRefreshToken);
return newAccessToken;
} catch (error) {
console.error("Failed to refresh token:", error);
logout(); // Log out if refresh fails
return null;
}
};
// Request Interceptor - Attaches access token
apiInstance.interceptors.request.use(
async (config) => {
const token = localStorage.getItem("access_token");
if (token) {
config.headers["Authorization"] = `Bearer ${token}`;
}
return config;
},
(error) => Promise.reject(error)
);
// Response Interceptor - Refreshes token if needed
apiInstance.interceptors.response.use(
(response) => response,
async (error) => {
const originalRequest = error.config;
if (error.response) {
// Check for 401 Unauthorized
if (error.response.status === 401) {
console.log("401 Unauthorized detected.");
}
// Check for 403 with token invalid message
if (error.response.status === 403 && error.response.data?.code === "token_not_valid") {
console.log("403 Forbidden detected with 'token_not_valid'.");
}
// Handle both cases
if ((error.response.status === 401 || error.response.status === 403) && !originalRequest._retry) {
console.log("Attempting token refresh...");
originalRequest._retry = true;
const newAccessToken = await refreshAccessToken();
if (newAccessToken) {
originalRequest.headers["Authorization"] = `Bearer ${newAccessToken}`;
return apiInstance(originalRequest);
} else {
console.log("Token refresh failed, logging out user.");
}
}
}
return Promise.reject(error);
}
);
// Login function
export const login = async (username: string, password: string) => {
const response = await apiInstance.post("/auth/token/", { username, password });
localStorage.setItem("access_token", response.data.access);
localStorage.setItem("refresh_token", response.data.refresh);
return response.data;
};
// Logout function
export const logout = () => {
localStorage.removeItem("access_token");
localStorage.removeItem("refresh_token");
window.location.href = "/user/login"; // Redirect to login page
};
// Fetch posts example
export const fetchPosts = async () => {
const response = await apiInstance.get("/posts/");
return response.data;
};
export default apiInstance;