Skip to content

Commit

Permalink
Auth (#12)
Browse files Browse the repository at this point in the history
* add basic auth config

* add authority++

* move values to env

* add authReq to msal service

* pass bearer token to backend

* remove console.log

* Update .gitignore

---------

Co-authored-by: Håkon Frøland <[email protected]>
  • Loading branch information
chribjel and hakonfro authored Sep 23, 2024
1 parent 4c05209 commit 2255ed2
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 11 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ dist-ssr

# bun
*.tsbuildinfo

# environment files
.env
Binary file modified bun.lockb
Binary file not shown.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"prepare": "husky"
},
"dependencies": {
"@azure/msal-browser": "^3.23.0",
"@azure/msal-react": "^2.0.22",
"@kvib/react": "4.5.0",
"@tanstack/react-query": "5.56.2",
"@tanstack/react-router": "1.58.3",
Expand Down
28 changes: 19 additions & 9 deletions src/routes/__root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,31 @@ import { Header } from "@/components/header";
import { Flex, FooterInline, KvibProvider } from "@kvib/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { createRootRoute, Outlet } from "@tanstack/react-router";
import { MsalAuthenticationTemplate, MsalProvider } from "@azure/msal-react";
import { InteractionType } from "@azure/msal-browser";
import { authenticationRequest, msalInstance } from "@/services/msal";

const queryClient = new QueryClient();

export const Route = createRootRoute({
component: () => (
<QueryClientProvider client={queryClient}>
<KvibProvider>
<Flex flexDirection="column" minHeight="100svh">
<Header />
<Outlet />
<footer>
<FooterInline />
</footer>
</Flex>
</KvibProvider>
<MsalProvider instance={msalInstance}>
<MsalAuthenticationTemplate
interactionType={InteractionType.Redirect}
authenticationRequest={authenticationRequest}
>
<KvibProvider>
<Flex flexDirection="column" minHeight="100svh">
<Header />
<Outlet />
<footer>
<FooterInline />
</footer>
</Flex>
</KvibProvider>
</MsalAuthenticationTemplate>
</MsalProvider>
</QueryClientProvider>
),
});
19 changes: 17 additions & 2 deletions src/services/backend.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
import { array, number, object, string, type z } from "zod";
import { msalInstance } from "./msal";

const BACKEND_URL = import.meta.env.VITE_BACKEND_URL ?? "http://localhost:8080";
const BEARER_TOKEN = import.meta.env.BEARER_TOKEN ?? "test123";

function getIdToken() {
const accounts = msalInstance.getAllAccounts();
const account = accounts[0];
if (!account) {
throw new Error("No active account");
}

const a = account.idToken;
if (!a) {
throw new Error("No id token");
}
return a;
}

// backend fetcher that appends the Bearer token to the request
async function fetchFromBackend(path: string, options: RequestInit) {
const idToken = getIdToken();
const response = await fetch(`${BACKEND_URL}${path}`, {
...options,
headers: {
...options.headers,
Authorization: `Bearer ${BEARER_TOKEN}`,
Authorization: `Bearer ${idToken}`,
},
});
if (!response.ok) {
Expand Down
47 changes: 47 additions & 0 deletions src/services/msal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import {
type Configuration,
type PopupRequest,
PublicClientApplication,
type RedirectRequest,
type SsoSilentRequest,
} from "@azure/msal-browser";

export const clientId = import.meta.env.VITE_CLIENT_ID;
const authority = import.meta.env.VITE_AUTHORITY;
const redirectUri = import.meta.env.VITE_LOGIN_REDIRECT_URI;

if (!clientId) {
throw new Error("Client ID is not set");
}
if (!authority) {
throw new Error("Authority is not set");
}
if (!redirectUri) {
throw new Error("Redirect URI is not set");
}

// MSAL configuration
const configuration: Configuration = {
auth: {
clientId,
authority,
redirectUri, // Points to window.location.origin. You must register this URI on Microsoft Entra admin center/App Registration.
postLogoutRedirectUri: "/", // Indicates the page to navigate after logout.
navigateToLoginRequestUrl: false, // If "true", will navigate back to the original request location before processing the auth code response.
},
cache: {
cacheLocation: "localStorage", // Configures cache location. "sessionStorage" is more secure, but "localStorage" gives you SSO between tabs.
storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
},
};

export const msalInstance = new PublicClientApplication(configuration);

export const scopes = import.meta.env.VITE_AUTH_SCOPES?.split(",") ?? [];

export const authenticationRequest:
| PopupRequest
| RedirectRequest
| SsoSilentRequest = {
scopes,
};

0 comments on commit 2255ed2

Please sign in to comment.