mirror of
https://github.com/muerwre/muerwre.github.io.git
synced 2025-04-25 02:46:39 +07:00
added whole content
This commit is contained in:
parent
1b5df685cb
commit
8b25e0631a
70 changed files with 5962 additions and 19 deletions
106
content/Frontend/React/Axios refresh token on React.md
Normal file
106
content/Frontend/React/Axios refresh token on React.md
Normal file
|
@ -0,0 +1,106 @@
|
|||
`<ApiProvider />` component, that will handle token refresh if needed. Refresh function should, probably, be passed through component props.
|
||||
|
||||
```typescript
|
||||
import axios from "axios";
|
||||
import React, {
|
||||
createContext,
|
||||
FC,
|
||||
PropsWithChildren,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useRef,
|
||||
} from "react";
|
||||
|
||||
interface APIProviderProps extends PropsWithChildren {
|
||||
tokens: {
|
||||
access: string;
|
||||
refresh: string;
|
||||
};
|
||||
logout: () => void;
|
||||
}
|
||||
|
||||
const APIContext = createContext({
|
||||
client: axios.create({
|
||||
baseURL: process.env.NEXT_PUBLIC_API_ENDPOINT,
|
||||
}),
|
||||
});
|
||||
|
||||
const APIProvider: FC<APIProviderProps> = ({
|
||||
tokens,
|
||||
logout,
|
||||
children,
|
||||
}) => {
|
||||
const client = useRef(
|
||||
axios.create({
|
||||
baseURL: process.env.NEXT_PUBLIC_API_ENDPOINT,
|
||||
})
|
||||
).current;
|
||||
|
||||
const refreshTokens = useCallback<() => string>(() => {
|
||||
// TODO: implement me
|
||||
throw new Error("not implemented");
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!tokens.access) {
|
||||
return;
|
||||
}
|
||||
|
||||
// append `access` token to all requests
|
||||
const req = client.interceptors.request.use(
|
||||
async (config) => {
|
||||
config.headers = {
|
||||
Authorization: `Bearer ${tokens.access}`,
|
||||
};
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// refreshing interceptor
|
||||
const resp = client.interceptors.response.use(
|
||||
(response) => {
|
||||
return response;
|
||||
},
|
||||
async function (error) {
|
||||
const originalRequest = error.config;
|
||||
|
||||
if (error.response.status === 401 && !originalRequest._retry) {
|
||||
originalRequest._retry = true;
|
||||
|
||||
const newToken = refreshTokens;
|
||||
|
||||
return axios({
|
||||
...originalRequest,
|
||||
headers: {
|
||||
...originalRequest.headers,
|
||||
Authorization: "Bearer " + newToken,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
logout();
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
return () => {
|
||||
axios.interceptors.request.eject(req);
|
||||
axios.interceptors.request.eject(resp);
|
||||
};
|
||||
}, [client, tokens.access, tokens.refresh, refreshTokens, logout]);
|
||||
|
||||
return (
|
||||
<APIContext.Provider value={{ client }}>
|
||||
{children}
|
||||
</APIContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useAPI = () => useContext(APIContext).client;
|
||||
|
||||
export { APIProvider };
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue