Skip to content

Latest commit

 

History

History
151 lines (94 loc) · 7.14 KB

README.md

File metadata and controls

151 lines (94 loc) · 7.14 KB

NextJS App Router and Passkeys Logo

App Router With WebAuthN

A web application that demonstrates a NextJS App Router project implementing user authentication with Passkeys using SimpleWebAuthn.

📚 Important Libraries

🤝 WebAuthN to Production

This project follows closely to Ian Mitchell's NextJS WebAuthN demo with the implementation being with NextJS App Router and Server Action Iron Session.

To take this this demo to a secure production application, you will additionally need to create a multi-step registration flow.

Per his note from his demo and blog:

If you're following this guide to add WebAuthn to an application you intend to ship, it's important to create a multi-step registration flow instead of asking for a username and email upfront. When you call create, the browser will create the login - your application can't remove it later. If your server validation fails (let's say because the username was registered by someone else) the browser will still have created an account.

Instead of having a registration all on one page, create a new model called Account, move username and email to that, and create a one-to-one relationship with the User model. Then, after a user clicks register and creates a User, prompt them for an email and username on a second page to create a new Account model. Any validation failures on this step won't impact the newly created User model and its Credential!

🚀 Usage

  1. Install project dependencies.

    Run

    pnpm install
  2. Set up the Iron Session instance:

    Create an .env file that contains the values to your secret cookie password needed for encrypted cookies with Iron Session.

    SECRET_COOKIE_PASSWORD=passwordpasswordpasswordpassword
  3. Set up the Drizzle database :

    We are using SQLite for our local file database. For an alternative database, you may set up your drizzle/db.ts and drizzle.config.ts differently for the appropriate database and driver.

    Initialize the new SQLite database

    Run

    pnpm push

    You have now generated the database file sqlite.db can now access a UI view of the tables

    Run

    pnpm drizzle-kit studio
  4. Run the web application.

    Run

    pnpm dev
  5. Register a User.

    Click Register to go to the Register page. Enter in a username and email for your passkey credential. Click Register.

    A prompt from the browser will come up that says Create a passkey for localhost with your email as the passkey identifier. Click Continue.

    A prompt from the device system will come up that says "Your Browser" is trying to verify your identity on localhost. Touch ID or enter your password to allow this. Enter in your Touch ID.

    Your passkey will now have been registered into the database.

  6. Login the User.

    Click Login to go to the Login page. Enter the email you used during the Register step. Click Login.

    A prompt from the device system will come up that says "Your Browser" is trying to verify your identity on localhost. Touch ID or enter your password to allow this. Enter in your Touch ID.

    You will now be re-directed to the Admin Page. The authenticated content will show your User ID number.

  7. Logout the User.

    From the Admin Page, click the Logout button. The cookies of your user session will be cleared and you will be re-directed to the Home Page.

🧐 What's inside?

A quick look at the top-level files and directories where we made our feature changes in the project.

lib
├── auth.ts
├── cookieActions.ts
├── database.ts
├── login.ts
├── register.ts
└── session.ts
drizzle
├── db.ts
└── schema.ts
src
└── app
     └── components
        ├── LoginPage.tsx
        ├── LogoutButton.tsx
        └── RegisterPage.tsx
  1. /lib: This directory will contain all of the use server internal functions that our components and functions will use.

  2. lib/auth.ts: This file contains the functions that create or modify the data or datatype of our variables so that they can be correctly passed into our function parameters and Prisma database.

  3. lib/cookieActions.ts: This file contains the functions that read and write encrypted cookies to and from cookie storage.

  4. lib/database.ts: This file contains the functions that read and write data to and from our Prisma database.

  5. lib/login.ts: This file contains the functions that are involved with the user log in process.

  6. lib/register.ts: This file contains the functions that are involved with the user registration process.

  7. lib/session.ts: This file sets up the Iron Session object used by the session functions in the lib/cookieAction.ts file.

  8. /drizzle: This directory will contain the drizzle files to set up and define our Drizzle database instance and tables.

  9. drizzle/db.ts: This file sets up the Drizzle database instance that is used by Drizzle functions in the /lib/database.ts and /lib/login.ts files.

  10. /drizzle/schema.ts: This is the configuration file that sets up Drizzle table data model definitions.

  11. /src/app: This directory will contain all of the code related to what you will see on the front-end of the site. src is a convention for “source code” and app is the convention for “app router”.

  12. src/app/components/LoginPage.tsx: This use client file contains the page component and client-side functions for the Login Page.

  13. src/app/components/LogoutButton.tsx: This use client file contains the logout button component that clears the cookies and redirects the user to the Home Page when clicked.

  14. src/app/components/RegisterPage.tsx: This use client file contains the page component and client-side functions for the Register Page.

📣 Recognition

Thank you to Matthew Miller for the creation and maintenance of the SimpleWebAuthn library and Ian Mitchell for his NextJS and WebAuthN blog that made creating this project possible.