npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

sveltekit-auth-example

v5.0.1

Published

SvelteKit Authentication Example

Downloads

261

Readme

SvelteKit Authentication and Authorization Example

Updated for Svelte 5 and SvelteKit 2.8.1

This is an example of how to register, authenticate, and update users and limit their access to areas of the website by role (admin, teacher, student). It includes profile management and password resets via SendGrid.

It's a Single Page App (SPA) built with SvelteKit and a PostgreSQL database back-end. Code is TypeScript and the website is styled using Bootstrap. PostgreSQL functions handle password hashing and UUID generation for the session ID. Unlike most authentication examples, this SPA does not use callbacks that redirect back to the site (causing the website to be reloaded with a visual flash).

The project includes a Content Security Policy (CSP) in svelte.config.js.

The website supports two types of authentication:

  1. Local accounts via username (email) and password
    • The login form (/src/routes/login/+page.svelte) sends the login info as JSON to endpoint /auth/login
    • The endpoint passes the JSON to PostgreSQL function authenticate(json) which hashes the password and compares it to the stored hashed password in the users table. The function returns JSON containing a session ID (v4 UUID) and user object (sans password).
    • The endpoint sends this session ID as an httpOnly SameSite cookie and the user object in the body of the response.
    • The client stores the user object in the loginSession store.
    • Further requests to the server include the session cookie. The hooks.ts handle() method extracts the session cookie, looks up the user and attaches it to RequestEvent.locals so server-side code can check locals.user.role to see if the request is authorized and return an HTTP 401 status if not.
  2. Sign in with Google
    • Sign in with Google is initialized in /src/routes/+layout.svelte.
    • Google One Tap prompt is displayed on the initially loaded page unless Intelligent Tracking Prevention is enabled in the browser.
    • Sign in with Google button is on the login page (/src/routes/login/+page.svelte) and register page (/src/routes/register/+page.svelte).
    • Clicking either button opens a new window asking the user to authorize this website. If the user OKs it, a JSON Web Token (JWT) is sent to a callback function.
    • The callback function (in /src/lib/auth.ts) sends the JWT to an endpoint on this server /auth/google.
    • The endpoint decodes and validates the user information then calls the PostgreSQL function start_gmail_user_session to upsert the user to the database returing a session id in an httpOnly SameSite cookie and user in the body of the response.
    • The client stores the user object in the loginSession store.
    • Further requests to the server work identically to local accounts above.

There is some overhead to checking the user session in a database each time versus using a JWT; however, validating each request avoids problems discussed in this article and this one. For a high-volume website, I would use Redis or the equivalent.

The forgot password / password reset functionality uses a JWT and SendGrid to send the email. You would need to have a SendGrid account and set two environmental variables. Email sending is in /src/routes/auth/forgot.ts. This code could easily be replaced by nodemailer or something similar. Note: I have no affliation with SendGrid (used their API in another project).

Prerequisites

  • PostgreSQL 14.10 or higher
  • Node.js 18.19.1 or higher
  • Google API client
  • Twilio SendGrid account (only used for emailing password reset link - the sample can run without it but forgot password will not work)

Setting up the project

Here are the steps:

  1. Get the project and setup the database
# Clone the repo to your current directory
git clone https://github.com/nstuyvesant/sveltekit-auth-example.git

# Install the dependencies
cd /sveltekit-auth-example
yarn install

# Create PostgreSQL database (only works if you installed PostgreSQL)
psql -d postgres -f db_create.sql
  1. Create a Google API client ID per these instructions. Make sure you include http://localhost:3000, http://localhost in the Authorized JavaScript origins and http://localhost:3000/auth/google/callback in the Authorized redirect URIs for your Client ID for Web application. ** Do not access the site using http://127.0.0.1:3000 ** - use http://localhost:3000 or it will not work.

  2. Create a free Twilio SendGrid account and generate an API Key following this documentation and add a sender as documented here.

  3. Create an .env file at the top level of the project with the following values (substituting your own id and PostgreSQL username and password):

DATABASE_URL=postgres://user:password@localhost:5432/auth
DOMAIN=http://localhost:3000
JWT_SECRET=replace_with_your_own
SENDGRID_KEY=replace_with_your_own
SENDGRID_SENDER=replace_with_your_own
PUBLIC_GOOGLE_CLIENT_ID=replace_with_your_own

Run locally

# Start the server and open the app in a new browser tab
yarn dev -- --open

Valid logins

The db_create.sql script adds three users to the database with obvious roles: