Created
July 9, 2023 07:57
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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