Created
May 27, 2020 15:48
-
-
Save Davi0k/e27bfa600311f4a2832d16fdd5bfd301 to your computer and use it in GitHub Desktop.
A small and useful authentication middleware for JWT apps which use node-fetch and a JS Storage to store Access and Refresh tokens written in Type-Script
This file contains hidden or 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 fetch, { Response } from "node-fetch"; | |
| export const API: string = "http://localhost:8000/api"; // The URL of your API to add to the endpoint of each request | |
| /** | |
| * Send a request using node-fetch and automatically inserting the user's access-token in the Authorization header. | |
| * | |
| * @param url - The URL to send the request to; | |
| * @param method - The verb/method with which to make the request, by default it is set to `"GET"`; | |
| * @param body - The body of the request if necessary, by default it is set to `null`; | |
| * | |
| * @returns The awaited response returned by the fetch function. | |
| * | |
| * @remarks The function works with Content-Type `application/json` and `multipart/form-data` but can be easily extended | |
| */ | |
| export async function authorization(url: string, method: string = "GET", body: any = null): Promise<Response> { | |
| const token: string = window.localStorage.getItem("access-token"); // Or any other way you want to use to retrieve the user's access-token | |
| const headers: HeadersInit = { | |
| "Accept": "application/json", | |
| "Authorization": `Bearer ${token}` | |
| }; | |
| if(body instanceof FormData == false) | |
| headers["Content-Type"] = "application/json"; | |
| return await fetch(url, { | |
| method, headers, | |
| body: (body ? body instanceof FormData ? body : JSON.stringify(body) : null) as any | |
| }); | |
| } | |
| /** | |
| * Send a request using node-fetch and, if the response status code matches `401 Unauthorized`, send a request to | |
| * refresh the` access-token` using the `refresh-token` of the authenticated user. | |
| * If the latter is successful, it will retry the first request and return the response, | |
| * otherwise it means that the user's session has expired. | |
| * | |
| * @param url - The URL to send the request to; | |
| * @param method - The verb/method with which to make the request, by default it is set to `"GET"`; | |
| * @param body - The body of the request if necessary, by default it is set to `null`; | |
| * | |
| * @returns The awaited response returned by the fetch function. | |
| * | |
| * @remarks The function works with Content-Type `application/json` and `multipart/form-data` but can be easily extended | |
| */ | |
| export async function middleware(url: string, method: string = "GET", body: any = null): Promise<Response> { | |
| let response: Response = await authorization(url, method, body); | |
| if(response.status == 401) { | |
| const body: any = { | |
| refresh: window.localStorage.getItem("refresh-token") // Or any other way you want to use to retrieve the user's refresh-token | |
| }; | |
| const refresh: Response = await fetch(`${API}/token/refresh`, { | |
| method: "POST", | |
| headers: { | |
| "Accept": "application/json", | |
| "Content-Type": "application/json", | |
| }, | |
| body: JSON.stringify(body) | |
| }); | |
| if(refresh.status == 400 || refresh.status == 401 || refresh.status == 403) | |
| // Handle the Out-Dated Session case (Force Log-out or whatever you want) | |
| const data: any = await refresh.json(); | |
| window.localStorage.setItem("access-token", data.access); | |
| response = await authorization(url, method, body); | |
| } | |
| return response; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment