Skip to content

Instantly share code, notes, and snippets.

@lionelB
Created May 14, 2020 07:41
Show Gist options
  • Save lionelB/65c0472304b18f9417665b5bce85991e to your computer and use it in GitHub Desktop.
Save lionelB/65c0472304b18f9417665b5bce85991e to your computer and use it in GitHub Desktop.
import Router from "next/router";
import { request } from "./request";
import { parse, serialize } from "cookie";
import { setRefreshTokenCookie } from "./setRefreshTokenCookie";
let token = null;
function getToken() {
return token ? token.jwt_token : null;
}
function isTokenExpired() {
if (!token) return true;
return Date.now() > new Date(token.jwt_token_expiry);
}
async function refreshToken(ctx) {
console.log("[ refreshToken ]", { token });
try {
let hostname = "";
const headers = {
"Cache-Control": "no-cache",
};
if (ctx && ctx.req) {
// node-fetch needs absolute url
hostname = `${ctx.req.protocol}://${ctx.req.headers.host}`;
const cookies = parse(ctx.req.headers.cookie);
if (cookies && cookies.refresh_token) {
headers["Cookie"] = serialize("refresh_token", cookies.refresh_token);
}
}
const tokenData = await request(`${hostname}/api/refresh_token`, {
credentials: "same-origin",
mode: "same-origin",
headers,
});
// for ServerSide call, we need to set the Cookie header
// to update the refresh_token value
if (ctx && ctx.res) {
setRefreshTokenCookie(ctx.res, tokenData.refresh_token);
}
setToken(tokenData);
} catch (error) {
console.error("[ refreshToken ]", { error });
if (ctx && ctx.res) {
ctx.res.writeHead(302, { Location: "/login" });
ctx.res.end();
return;
} else {
Router.push("/login");
return;
}
}
return token.token;
}
function setToken(tokenData) {
console.log("[ setToken ]", { tokenData });
token = { ...tokenData };
}
async function logout() {
token = null;
try {
await request("/api/logout", {
credentials: "same-origin",
mode: "same-origin",
});
} catch (error) {
console.error("[ client logout ] failed");
}
}
export { getToken, isTokenExpired, logout, refreshToken, setToken };
export function request(endpoint, { body, ...customConfig } = {}) {
const config = {
method: body ? "POST" : "GET",
...customConfig,
headers: {
"Content-Type": "application/json",
...customConfig.headers,
},
};
if (body) {
config.body = JSON.stringify(body);
}
console.log("[request]", endpoint);
return fetch(endpoint, config).then(async (response) => {
const data = await response.json();
if (response.ok) {
return data;
} else {
return Promise.reject(data);
}
});
}
import cookie from "cookie";
export function setRefreshTokenCookie(res, refresh_token) {
res.setHeader(
"Set-Cookie",
cookie.serialize("refresh_token", refresh_token, {
// sameSite: "lax",
secure: process.env.NODE_ENV === "production",
maxAge: (process.env.REFRESH_TOKEN_EXPIRES || 43200) * 60, // maxAge in second
httpOnly: true,
path: "/",
})
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment