This content originally appeared on DEV Community and was authored by pilcrowOnPaper
I recently released Lucia, an authentication library for SvelteKit. It handles the bulk of the authentication process and makes it easier to implement authentication to your SvelteKit project. Unlike other libraries, it isn't an out-of-the-box authentication library and requires a bit more time to start, but can be fully customized once you know the basics. It doesn't just create tokens, it uses short-lived access tokens with refresh tokens, auto-refreshes them, implements rotating refresh token, and detects refresh token theft.
This guide will cover how to implement email and password authentication, at least the sign in part of it. I'm going to gloss over some parts that are better explained in the documentation.
Setup
The basic set up is explained here.
Database
Refer to adapters for database-specific explanation. Add a new column called email
(text/varchar) where the values are unique.
Frontend
Send a POST request to the signup or login endpoint with a JSON body.
const signup = async () => {
await fetch("/api/signup", {
method: "POST",
body: JSON.stringify({
email,
password,
}),
});
};
Sign up
Create routes/api/signup.ts
and accept a POST request. Get the email and password from the body data.
import type { RequestHandler } from "@sveltejs/kit";
import { auth } from "$lib/lucia";
export const POST: RequestHandler = async ({ request }) => {
const { email, password } = await request.json();
if (!email || !password) {
return {
status: 400,
};
}
};
Create a new user
Create a new user using createUser
using the auth id of email
and an identifier of email
. Auth ids represent the authentication method used (for Github OAuth, "github"), and identifier represents the user within that method (usernames or email for GitHub). It's used to identify users and not to store user data (if you need to store the user's email, create a email column in your db).
Refer to the overview page for an explanation on auth ids and identifiers.
Save the user's password using the password options and the user's email using user_data
. Set the cookies (refresh, access, and fingerprint token) and redirect the user in the response. The AUTH_DUPLICATE_IDENTIFER_TOKEN
error is thrown when a user tries to create a new account using the same auth id and identifer (in this case, email).
try {
const createUser = await auth.createUser("email", email, {
password,
user_data: {
email,
},
});
return {
status: 302,
headers: {
"set-cookie": createUser.cookies,
location: "/",
},
};
} catch (e) {
const error = e as Error;
if (
error.message === "AUTH_DUPLICATE_IDENTIFER_TOKEN" ||
error.message === "AUTH_DUPLICATE_USER_DATA"
) {
return {
status: 400,
body: JSON.stringify({
error: "Email already in use.",
}),
};
}
return {
status: 500,
body: JSON.stringify({
error: "Unknown error.",
}),
};
}
Sign in
Create routes/api/login.ts
and accept a POST request. Get the user's email and password from the body.
import type { RequestHandler } from "@sveltejs/kit";
import { auth } from "$lib/lucia";
export const POST: RequestHandler = async ({ request }) => {
const form = await request.formData();
const email = form.get("email")?.toString();
const password = form.get("password")?.toString();
if (!email || !password) {
return {
status: 400,
};
}
};
Authenticate a user
Authenticate the user using authenticateUser
, which will require a password in the third parameter. The auth id should be the same as the one used when creating the user. It's important to NOT tell the user if the email was incorrect or if the password was incorrect.
try {
const authenticateUser = await auth.authenticateUser(
"email",
email,
password
);
return {
status: 302,
headers: {
"set-cookie": createUser.cookies,
location: "/",
},
};
} catch (e) {
const error = e as Error;
if (
error.message === "AUTH_INVALID_IDENTIFIER_TOKEN" ||
error.message === "AUTH_INVALID_PASSWORD"
) {
return {
status: 400,
body: JSON.stringify({
error: "Incorrect email or password.",
}),
};
}
// database connection error
return {
status: 500,
body: JSON.stringify({
error: "Unknown error.",
}),
};
}
That's it. Other parts of Lucia and authentication (like token refresh and protected routes) are explained in getting started.
This content originally appeared on DEV Community and was authored by pilcrowOnPaper
pilcrowOnPaper | Sciencx (2022-07-22T14:09:00+00:00) SvelteKit + Lucia: Email and password authentication. Retrieved from https://www.scien.cx/2022/07/22/sveltekit-lucia-email-and-password-authentication/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.