Published
Edited
Aug 24, 2022
Importers
5 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
async function createCustomToken({
private_key,
client_email
} = {}, uid, additionalClaims, additionalFields = {}) {
const now_secs = Math.floor(Date.now() / 1000);
const sHeader = JSON.stringify({alg: 'RS256', typ: 'JWT'});
const sPayload = JSON.stringify({
"iss": client_email,
"sub": client_email,
"aud": "https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit",
"iat": now_secs,
"exp": now_secs + 60 * 60,
"uid": uid,
...(additionalClaims && {"claims": additionalClaims}),
...additionalFields,
});
return jsrsasign.KJUR.jws.JWS.sign("RS256", sHeader, sPayload, private_key);
}
Insert cell
Insert cell
async function verifyCustomToken(firebase, token) {
const API_KEY = firebase.options_.apiKey;
if (!token) throw new Error("No token specified");
if (!API_KEY) throw new Error("Cannot find API_KEY");
// Simplest way is to try to exchange for ID token
// https://cloud.google.com/identity-platform/docs/use-rest-api
const response = await fetch(
`https://identitytoolkit.googleapis.com/v1/accounts:signInWithCustomToken?key=${API_KEY}`,
{
method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: `{"token":"${token}","returnSecureToken":true}`
}
);
if (response.status !== 200) throw new Error(await response.text());
else {
return JSON.parse(atob(token.split('.')[1]));
}
}
Insert cell
Insert cell
async function getAccessTokenFromServiceAccount(
serviceAccountKey,
{
scope = "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/cloud-platform"
} = {}
) {
if (typeof serviceAccountKey === "string") {
serviceAccountKey = JSON.parse(serviceAccountKey);
}
// First create a JWT from the credentials
const tNow = Math.floor(new Date().getTime() / 1000);
const sHeader = JSON.stringify({ alg: "RS256", typ: "JWT" });
const sPayload = JSON.stringify({
iss: serviceAccountKey.client_email,
scope: scope,
iat: tNow,
exp: tNow + 600,
aud: "https://oauth2.googleapis.com/token"
});
const JWT = jsrsasign.KJUR.jws.JWS.sign(
"RS256",
sHeader,
sPayload,
serviceAccountKey.private_key
);

// Swap JWT for access_token
const tokenResponse = await fetch("https://oauth2.googleapis.com/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: `grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=${JWT}`
});

if (tokenResponse.status != 200) {
throw new Error(await tokenResponse.text());
}
return (await tokenResponse.json()).access_token;
}
Insert cell
Insert cell
async function signinWithAccessToken(firebase, access_token) {
const credential = firebase.firebase_.auth.GoogleAuthProvider.credential(
null,
access_token
);
return await firebase.auth().signInWithCredential(credential);
}
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more