Originally posted on my blog.
Want to add simple authentication to a page, say an admin section or a demo app, in SvelteKit? Well, HTTP Basic Auth might be what you're looking for.
But before we start, you should be aware that HTTP Basic Auth is not considered very secure since you're sending the username/password as base64 encoded, amongst other concerns. If you use HTTPS (which you should be doing!), then this particular attack vector is less of a concern, but you should still consider these factors and you should absolutely not use it with customer/user facing logins. I see HTTP Basic as a useful and quick way to (somewhat) secure a page or section on your site. If you choose HTTP Basic, just be aware that the pages you're securing may not be as secure as you might think.
Ok, moving on!
In order to accomplish this, we will need to intercept all server-side requests using the handle
hook which gets called on every request.
We will then check the URL pathname to see if it starts with /admin
so that any page under and including /admin
will get secured behind HTTP Basic Auth (e.g. /admin
, /admin/reports
).
Then we check for an Authorization
header to see if the user has attempted logged in (or if they cancel the login dialog) and we check it against a username:password combo (base64 encoded). If it doesn't match, then they are not logged in so we indicate they're not authorized with a 401
error.
If they succeed with login by typing in the correct username:password combo, then they will be directed to the admin page they wanted.
import type { Handle } from "@sveltejs/kit";
import { ADMIN_LOGIN } from "$env/static/private";
export const handle: Handle = async ({ event }) => {
const url = new URL(event.request.url);
if (url.pathname.startsWith("/admin")) {
const auth = event.request.headers.get("Authorization");
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);
};
Then, in your .env
file (as well as set in your hosting provider's environment variable management system), set your username/password combo:
ADMIN_LOGIN="admin:sekret"
And now make sure to create a page at /admin
or somewhere else and attempt to load it. You should see the login prompt and on inputting admin
for the username and sekret
for the password, you should see the admin Svelte page.
Follow me on Dev.to, Twitter and Github for more web dev and startup related content
Top comments (2)
Client certificate check can help to make this way safer for using on internal portals or backoffice apps
Thank you! It was of great help.