HTTP Basic Auth with Svelte
Recently I started to explore using the Svelte framework for fronted UI applications, especially to build a more interactive, design-driven user interface for IBM watsonx application. Exposing directly the UI application over the Internet via Techzone may not be a good idea. The simple way is to implement HTTP Basic Auth on Svelte application rather than build then entire user authentication module within Svelte.
This is where I found out there is a Svelte component library based on IBM Carbon system. This made my life much easier to bootstrap an IBM Carbon Design application. The full documentation of Carbon Components Svelte is available at https://svelte.carbondesignsystem.com/. Clear documentation makes it easy for a developer to understand what component is available with some examples, what action it can trigger (e.g.: on click), icons, and so on.
To implement HTTP Basic Authentication, the easiest way is to implement Hooks
in Svelte (https://kit.svelte.dev/docs/hooks). What it does is to intercept all the HTTP requests. A new file hooks.server.ts
is created and a simple logic to validate the header Authrozation
against the username and password. Username and password can be stored as environment variables.
#hooks.server.ts
import { ADMIN_LOGIN } from '$env/static/private';
// @ts-ignore
export const handle = async ({ event, resolve }) => {
// @ts-ignore
const url = new URL(event.request.url);
const auth = event.request.headers.get('Authorization');
// @ts-ignore
if (auth !== `Basic ${btoa(ADMIN_LOGIN)}`) {
return new Response('Not authorized', {
status: 401,
headers: {
'WWW-Authenticate': 'Basic realm="User Visible Realm", charset="UTF-8"'
}
});
}
return resolve(event);
};
#.env
ADMIN_LOGIN=admin:pass
To test it, just need to run npm run dev
Looks good. Let’s compile it into production code and deploy it as a container with the command npm run build
. Gosh.. build error happened.
One of the good features of Svelte is prerendering
. The definition of prerendering
at here. Svelte build process tends to crawl all the links in the application and pre-render the page as static HTML (that’s why it is fast). The error happened when the svelte-prerender crawled a protected URL, in this case, the very first place of this application /
.
The resolution for this to tell Svelte is to do the following:
- In Use
adaptor-node
and includeprerender
section to ignore HTTP error at path/
. You may need to donpm install @sveltejs/adapter-node --save
to install the correct adapter.
//svelte.config.js
import adapter from '@sveltejs/adapter-node';
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors
preprocess: vitePreprocess(),
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter(),
csrf: {
checkOrigin: false,
},
prerender: {
handleHttpError: "ignore",
crawl: false,
entries: ["/"],
},
}
};
export default config;
- In
+page.ts
, set prerender to false
// +page.ts
export const prerender = false;
Let’s try to build it again with npm run build
. In this case the build is successful.
Let’s do more tests by running commandnpm run preview
.
Please take note that if you tend to generate dynamic content by calling API (e.g.: calling fetch
) from /
, it is a must to use adapter-node
.
Full source code is available at https://github.com/ongkhaiwei/carbon-portal