5. Implementasi Refresh Token
Kenapa harus menggunakan Refresh Token
Api Refresh Token
response endpoint refresh token
{
"status": "Success",
"message": "Success",
"data": {
"id": 1,
"nama": "ihsan santana w",
"email": "ihsanabuhanifah@gmail.com",
"password": "$2b$12$otdHLxtVDZq05dQAVccfpOH20OTJ57cg7kuAuzWkh3gWuaQrbA4YG",
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwibmFtYSI6Imloc2FuIHNhbnRhbmEgdyIsImVtYWlsIjoiaWhzYW5hYnVoYW5pZmFoQGdtYWlsLmNvbSIsImlhdCI6MTY5NTYwNDQwMCwiZXhwIjoxNjk2MjA5MjAwfQ.q4lzXbvXDTt-WmOru1MXDipDGsAkfELLNQC3BQLOo4U",
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwibmFtYSI6Imloc2FuIHNhbnRhbmEgdyIsImVtYWlsIjoiaWhzYW5hYnVoYW5pZmFoQGdtYWlsLmNvbSIsImlhdCI6MTY5NTYwNDQwMCwiZXhwIjoxNjk1NjA0NDMwfQ.BuDhbSEIwc8zc_WUZCE2cgfwBjcRD0RfvzdxuzQ3oZY"
}
}
Membuat axiosClientRefresh
lib/axiosClient
import axios, { AxiosInstance } from "axios";
export const axiosClient: AxiosInstance = axios.create({
baseURL: "http://localhost:5002",
headers: { "Content-Type": "application/json" },
});
export const axiosClientRefresh: AxiosInstance = axios.create({
baseURL: "http://localhost:5002",
headers: { "Content-Type": "application/json" },
});
export interface BaseResponseSuccess {
status: string;
message: string;
data: any[] | any;
}
export interface BaseResponsePagination {
status: string;
message: string;
data: any[];
pagination: {
page: number;
total_page: number;
pageSize: number;
total: number;
};
}
export interface BasePayloadPagination {
page: number;
pageSize: number;
}
Membuat hook useRefreshToken
hook/useRefeshToken.ts
import { axiosClientRefresh } from "@/lib/axiosClient";
import { signOut, useSession } from "next-auth/react";
import { Session } from "next-auth";
import { useEffect } from "react";
import { useToast } from ".";
interface SessionUser {
id: number;
refreshToken: string;
accessToken: string;
name: string;
email: string;
}
export const useRefreshToken = () => {
const { data: session, update } = useSession();
const { toastWarning } = useToast();
useEffect(() => {
const requestIntercept = axiosClientRefresh.interceptors.request.use(
(config: any) => {
config.headers[
"Authorization"
] = `Bearer ${session?.user?.refreshToken}`;
config.headers.id = session?.user?.id;
return config;
},
(error: any) => Promise.reject(error)
);
const responseIntercept = axiosClientRefresh.interceptors.response.use(
async (response: any) => response,
async (error: any) => {
toastWarning(error.response.message);
// signOut();
// window.location.replace("/auth/login");
}
);
return () => {
axiosClientRefresh.interceptors.request.eject(requestIntercept);
axiosClientRefresh.interceptors.response.eject(responseIntercept);
};
}, [session, toastWarning]);
const refreshToken = async () => {
if (!session) return;
try {
const { user } = session as Session & { user: SessionUser };
const res = await axiosClientRefresh.get("/auth/refresh-token");
console.log('res', res.data)
await update({
...session,
user: {
...user,
accessToken: res.data.data.access_token,
refreshToken: res.data.data.refresh_token,
},
});
return true;
} catch {
return false;
}
};
return { refreshToken };
};
Implementasi pada useAxiosAuth
hook/useAxiosAuth.ts
import { axiosClient } from "@/lib/axiosClient";
import { useSession, signOut } from "next-auth/react";
import { useEffect } from "react";
import { useRefreshToken } from "./useRefeshToken";
const useAxiosAuth = () => {
const { data: session } = useSession();
const { refreshToken } = useRefreshToken();
useEffect(() => {
const requestIntercept = axiosClient.interceptors.request.use(
(config: any) => {
config.headers[
"Authorization"
] = `Bearer ${session?.user?.accessToken}`;
return config;
},
(error: any) => Promise.reject(error)
);
const responseIntercept = axiosClient.interceptors.response.use(
async (response: any) => response,
async (error: any) => {
const prevRequest = error?.config;
if (401 === error?.response?.status && !prevRequest?.sent) {
prevRequest.sent = true;
try {
await refreshToken();
prevRequest.headers[
"Authorization"
] = `Bearer ${session?.user?.accessToken}`;
return axiosClient(prevRequest);
} catch (err) {
signOut();
window.location.replace("/auth/login");
}
} else {
return Promise.reject(error);
}
}
);
return () => {
axiosClient.interceptors.request.eject(requestIntercept);
axiosClient.interceptors.response.eject(responseIntercept);
};
}, [session, refreshToken]);
return axiosClient;
};
export default useAxiosAuth;