Skip to content

Instantly share code, notes, and snippets.

@hargun0360
Created July 9, 2023 07:57
Show Gist options
  • Save hargun0360/52342fc0feda77b0d105d5b3efa7a06f to your computer and use it in GitHub Desktop.
Save hargun0360/52342fc0feda77b0d105d5b3efa7a06f to your computer and use it in GitHub Desktop.
A Comprehensive Overview of How to Handle Refresh Token Using a Custom Function.
import axios from "axios"; // Import axios library for HTTP requests
// API_URLs
const BASE_URL = "http://117.55.243.59:8000/api/"; // Base URL
const REFRESH_TOKEN = BASE_URL + 'token/refresh/'; // Refresh token API endpoint
// Function to fetch Auth Token from Local Storage
export function getAuthToken(key = "access_token") {
// Fetch token from local storage
return localStorage.getItem(key);
}
// Function to refresh Access Token
function doGetRefreshToken() {
let headers = { "Content-Type": "application/json" } // Set headers
let data = { "refresh": getAuthToken("refresh_token") } // Set request body with refresh token
// Return promise object for async operations
return new Promise((resolve, reject) => {
// Make POST request to refresh token API endpoint with headers and data
return RestAxiosService(REFRESH_TOKEN, "POST", data, headers).then(
res => {
// On successful response, store new access token in local storage
if (res.status === 200) {
localStorage.setItem("access_token", res.data.access);
} else if (res.status === 401) {
// On unauthorized response, clear local storage and redirect to homepage
localStorage.clear();
window.location.href = "/";
} else return; // If status code is neither 200 nor 401, exit function
},
err => {
reject(err); // On request failure, reject promise
}
);
});
}
// Function to perform HTTP requests
export function RestAxiosService(url, method, body, headers) {
let options = { // Define request options
url: url,
method: method,
data: body,
headers: { ...headers }
};
// For GET requests, remove 'data' field from options since GET requests do not send a body.
if (method.toLowerCase() === "get") {
delete options.data;
}
// Return promise object for async operations
return new Promise((resolve, reject) => {
// Perform HTTP request with options
return axios(options)
.then((res) => {
// If status code indicates success, resolve promise with response data
if (res.status >= 200 && res.status < 300) {
resolve({ status: res.status, data: res.data });
} else {
// Otherwise, reject promise with response data
reject({ status: res.status, data: res.data });
}
})
.catch((e) => {
// If there's a response object and URL doesn't include "/token/refresh/"
if (typeof e === "object" && typeof e.response === "object") {
if (url.indexOf("/token/refresh/") === -1) {
// If status code is 406 (Not Acceptable), attempt to refresh token
if (e.response.status == 406) {
doGetRefreshToken().then(
(res) => {
// If status code indicates success, retry original request with new access token
if (res.status >= 200 && res.status < 299) {
let updatedHeaders = {
...headers,
Authorization: "Bearer " + getAuthToken("access_token"),
};
RestAxiosService(url, method, body, updatedHeaders).then(
retryResponse => { resolve(retryResponse); },
retryError => { reject(retryError); }
);
}
// If status code is 401, it means that the refresh token is also expired.
else if (res.status == 401) {
// Clear local storage and redirect to homepage
window.location.href = "/";
localStorage.clear();
} else return;
},
(err) => {
// If status code is 405 (Method Not Allowed) and user is not on homepage.
if (err.status == 405 && ["/"].indexOf(window.location.pathname) === -1) {
// Clear local storage and redirect to homepage
window.location.href = "/";
localStorage.clear();
}
}
);
} else {
// If URL includes "/token/refresh/", reject promise with response data
reject({ status: e.response.status, data: e.response.data });
}
} else {
reject({ status: e.response.status, data: e.response.data });
}
} else {
// If unexpected error occurred, reject promise with custom status code and error message
reject({ status: 532, data: "Internet Connection Failure" });
}
});
});
}
// Now the application API's can manage here or
// The ApiServices.js file serves as a centralized location for managing all the API requests in our application
// We begin by constructing the URL endpoint for user login.
const LOGIN_URL = BASE_URL + 'login/';
// This function for logging in the user.
export function doLoginUser(credentials) {
// We define the headers which telling the server that we are sending JSON data.
let headers = {
"Content-Type": "application/json",
}
return new Promise((resolve, reject) => {
// Calling the RestAxiosService with necessary details.
return RestAxiosService(LOGIN_URL, "POST", credentials, headers).then(
res => {
// If successful, resolve the Promise with the server response.
resolve(res)
},
err => {
// If an error occurs, reject the Promise with the error.
reject(err)
}
)
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment