From afea3d9e36ac3414031e6afe61f5d478407d2da7 Mon Sep 17 00:00:00 2001 From: "tom.wolf" Date: Thu, 23 Dec 2021 00:08:59 +0200 Subject: [PATCH 1/2] Updating tutorial to work with latest backstage Signed-off-by: tom.wolf --- .../tutorials/authenticate-api-requests.md | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/contrib/docs/tutorials/authenticate-api-requests.md b/contrib/docs/tutorials/authenticate-api-requests.md index 9f651ddd1a..16c42fe464 100644 --- a/contrib/docs/tutorials/authenticate-api-requests.md +++ b/contrib/docs/tutorials/authenticate-api-requests.md @@ -13,7 +13,7 @@ As techdocs HTML pages load assets without an Authorization header the code belo import cookieParser from 'cookie-parser'; import { Request, Response, NextFunction } from 'express'; -import { JWT } from 'jose'; +import jwtDecoder from 'jwt-decode'; import { URL } from 'url'; import { IdentityClient } from '@backstage/plugin-auth-backend'; @@ -24,7 +24,7 @@ function setTokenCookie( options: { token: string; secure: boolean; cookieDomain: string }, ) { try { - const payload = JWT.decode(options.token) as object & { + const payload = jwtDecoder(options.token) as any & { exp: number; }; res.cookie(`token`, options.token, { @@ -129,8 +129,15 @@ function msUntilExpiry(token: string): number { // Calls the specified url regularly using an auth token to set a token cookie // to authorize regular HTTP requests when loading techdocs -async function setTokenCookie(url: string, getIdToken: () => Promise) { - const token = await getIdToken(); +async function setTokenCookie(url: string, identityApi: IdentityApi) { + const { token } = await identityApi.getCredentials(); + if (!token) { + // In some cases, the token might be undefined - we will wait 10 seconds + // to try this again. + setTimeout(setTokenCookie, 10 * 1000, url, identityApi); + return; + } + await fetch(url, { mode: 'cors', credentials: 'include', @@ -138,11 +145,12 @@ async function setTokenCookie(url: string, getIdToken: () => Promise) { Authorization: `Bearer ${token}`, }, }); + // Call this function again a few minutes before the token expires const ms = msUntilExpiry(token) - 4 * 60 * 1000; setTimeout( () => { - setTokenCookie(url, getIdToken); + setTokenCookie(url, identityApi); }, ms > 0 ? ms : 10000, ); @@ -160,16 +168,13 @@ const app = createApp({ providers={['guest', 'custom', ...providers]} title="Select a sign-in method" align="center" - onResult={async result => { - // When logged in, set a token cookie - if (typeof result.getIdToken !== 'undefined') { - setTokenCookie( - await discoveryApi.getBaseUrl('cookie'), - result.getIdToken, - ); - } - // Forward results - props.onResult(result); + onSignInSuccess={async (identityApi: IdentityApi) => { + setTokenCookie( + await discoveryApi.getBaseUrl('cookie'), + identityApi, + ); + + props.onSignInSuccess(identityApi); }} /> ); From 5f2e4bd1803a7300022b0ac34614b3ff8cfcfc0c Mon Sep 17 00:00:00 2001 From: "tom.wolf" Date: Tue, 28 Dec 2021 22:15:17 +0200 Subject: [PATCH 2/2] Returning usage of 'jose" and removing the null token retry code Signed-off-by: tom.wolf --- contrib/docs/tutorials/authenticate-api-requests.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/contrib/docs/tutorials/authenticate-api-requests.md b/contrib/docs/tutorials/authenticate-api-requests.md index 16c42fe464..803a6babc7 100644 --- a/contrib/docs/tutorials/authenticate-api-requests.md +++ b/contrib/docs/tutorials/authenticate-api-requests.md @@ -13,7 +13,7 @@ As techdocs HTML pages load assets without an Authorization header the code belo import cookieParser from 'cookie-parser'; import { Request, Response, NextFunction } from 'express'; -import jwtDecoder from 'jwt-decode'; +import { JWT } from 'jose'; import { URL } from 'url'; import { IdentityClient } from '@backstage/plugin-auth-backend'; @@ -24,7 +24,7 @@ function setTokenCookie( options: { token: string; secure: boolean; cookieDomain: string }, ) { try { - const payload = jwtDecoder(options.token) as any & { + const payload = JWT.decode(options.token) as object & { exp: number; }; res.cookie(`token`, options.token, { @@ -132,9 +132,6 @@ function msUntilExpiry(token: string): number { async function setTokenCookie(url: string, identityApi: IdentityApi) { const { token } = await identityApi.getCredentials(); if (!token) { - // In some cases, the token might be undefined - we will wait 10 seconds - // to try this again. - setTimeout(setTokenCookie, 10 * 1000, url, identityApi); return; }