Refactor API fetch functions: implement useApiFetch composable for improved token handling and error management; update cfetch to streamline authorization logic and enhance error handling
This commit is contained in:
1 parent
fbf1fcf553
commit
66ebf25b28
2 files changed
+70
-2
No files matched your search
@@ -0,0 +1,49 @@
|
|||||||
|
import type { UseFetchOptions } from "#app"
|
||||||
|
import defu from "defu"
|
||||||
|
|
||||||
|
export function useApiFetch<DataT = any, ErrorT = any>(
|
||||||
|
url: string | Request | Ref<string | Request> | (() => string | Request),
|
||||||
|
options: UseFetchOptions<DataT, ErrorT> = {},
|
||||||
|
authorize: boolean = true
|
||||||
|
) {
|
||||||
|
const baseUrl = import.meta.env.VITE_PUBLIC_BACKEND
|
||||||
|
|
||||||
|
if (!baseUrl) throw new Error("BACKEND URL not set")
|
||||||
|
|
||||||
|
const { sessionToken, refreshSessionToken } = useAuth()
|
||||||
|
|
||||||
|
const defaults: UseFetchOptions<DataT, ErrorT> = {
|
||||||
|
baseURL: baseUrl,
|
||||||
|
|
||||||
|
headers:
|
||||||
|
authorize && sessionToken.value
|
||||||
|
? { Authorization: `Bearer ${sessionToken.value}` }
|
||||||
|
: {},
|
||||||
|
onResponseError: async ({ response, options }) => {
|
||||||
|
if (response.status == 401 && authorize) {
|
||||||
|
const newToken = await refreshSessionToken()
|
||||||
|
|
||||||
|
if (!newToken) return
|
||||||
|
|
||||||
|
const newOptions = {
|
||||||
|
...options,
|
||||||
|
headers: {
|
||||||
|
...(options.headers || {}),
|
||||||
|
Authorization: `Bearer ${newToken}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
return await $fetch<DataT, ErrorT>(url, newOptions)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = defu(options || {}, defaults) as UseFetchOptions<
|
||||||
|
DataT,
|
||||||
|
ErrorT
|
||||||
|
>
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
return useFetch<DataT, ErrorT>(url, config)
|
||||||
|
}
|
||||||
+21
-2
@@ -10,17 +10,36 @@ export const cfetch = async (
|
|||||||
|
|
||||||
if (!baseUrl) throw new Error("BACKEND URL not set")
|
if (!baseUrl) throw new Error("BACKEND URL not set")
|
||||||
|
|
||||||
|
const { sessionToken, refreshSessionToken } = useAuth()
|
||||||
|
|
||||||
const defaults: AxiosRequestConfig = {
|
const defaults: AxiosRequestConfig = {
|
||||||
baseURL: baseUrl,
|
baseURL: baseUrl,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (authorize) {
|
if (authorize) {
|
||||||
let token = (await cookieStore.get("sessionToken"))?.value
|
let token = sessionToken.value
|
||||||
|
|
||||||
if (token) defaults.headers = { Authorization: `Bearer ${token}` }
|
if (token) defaults.headers = { Authorization: `Bearer ${token}` }
|
||||||
|
else
|
||||||
|
defaults.headers = {
|
||||||
|
Authorization: `Bearer ${await refreshSessionToken()}`,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const config: AxiosRequestConfig = defu(options, defaults)
|
const config: AxiosRequestConfig = defu(options, defaults)
|
||||||
|
|
||||||
return await axios(url, config)
|
let response
|
||||||
|
try {
|
||||||
|
response = await axios(url, config)
|
||||||
|
} catch {
|
||||||
|
if (response?.status == 401) {
|
||||||
|
if (!config.headers) config.headers = {}
|
||||||
|
config.headers.Authorization = `Bearer ${await refreshSessionToken()}`
|
||||||
|
|
||||||
|
response = await axios(url, config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!response) throw new Error("Something went wrong. Please try again")
|
||||||
|
return response
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user