Using Hanko Auth for a Todo app with Next.js 13 and Prisma
create-next-app
or create-next-app@latest
command-line tool followed by the name of your choice for the app. Open your terminal in Visual Studio Code and run the following command:
tailwind.config.ts
file, defining your color palette, fonts, breakpoints, etc.
prisma
directory with your Prisma schema file and configures SQLite as your database. Once we also create the “Todo” model, the Prisma schema file should look like this:
prisma/migrations
directory.prisma
directory with the name dev.db
as defined via the environment variable in the .env
file.
To prevent problems when instantiating PrismaClient, on the Prisma Docs there’s a section dedicated to the best practice to do it. Let’s try it by creating a db.ts
file in the root of the app and add the following code inside:
page.tsx
is like the new index.tsx
, which means that this name will play an important role when creating a new route. You can define a page by exporting a component from a page.tsx
file.
Now you can update the page.tsx
file to display “Hello World” as done below.
app
directory, create a new todo
folder with a page.tsx
file inside of it. Use the code below as the todo/page.tsx
contents:
route.ts|js
file inside the app
directory. Read more about the Route Handlers in the Next.js Docs.
Inside the app
directory create an api
folder. We will group our Route Handlers as follows: one directory todo
with a route.tsx
which will contain the POST
HTTP method handler for creating a new todo, and in that same directory we will use a dynamic route to GET
and DELETE
todos. Should look like the following example:
components
folder at the root directory, then create a components/todos/NewTodo.tsx
file and use the following as its contents:
useState()
and subscribing to interactive events.
This is how we call Prisma to create the todo inside the api/todo/route.ts
Route Handler:
todo/page.tsx
file to get all our todos, then we pass them to our components/todos/TodoItem.tsx
file to be displayed. This is how the todo/page.tsx
should look after our changes:
update
and delete
functions that fetch our dynamic route. This would be the components/todos/TodoItem.tsx
file:
api/todo/[id]/route.tsx
Route Handler:
@teamhanko/hanko-elements
package running the code below:
@teamhanko/hanko-elements
, and call the function with the Hanko API URL as an argument to register the <hanko-auth>
. Now include it in your JSX:
<hanko-profile>
component offers a page for managing email addresses and passkeys. Let’s create a profile button component by creating a file components/Profile.tsx
and use the following code as its content:
@teamhanko/hanko-elements
to manage user logouts by creating a logout button component. Create a file components/Logout.tsx
and use the following as its content:
What are JWTs? > A JSON Web Token (JWT) is a compact and self-contained way for transmitting information between parties as a JSON object in a secure way. The purpose of a JWT is to ensure the authenticity of the data.
Hanko handles the authentication and signing of the JWT. On successful authentication with Hanko a cookie, which contains said JWT as its value, is set. We don’t really need to know a lot about JWTs, but it’s worth getting familiar with the parts of a JWT (header, payload and signature), and with what a JWKS is. For more information you can visit JWT.io.
To verify the JWT we need to install the jose
package:
jose
is a JavaScript module that supports JWT and provides functionality for signing and verifying tokens.
jose
click here.middleware.tsx
in the root of your project and use the following code:
createRemoteJWKSet
function from jose. Then we call await jose.jwtVerify(token, JWKS)
. If the token can be verified, then the promise returned from the function resolves to a decoded token. If it cannot be verified, then the promise rejects and we can catch the error and handle it appropriately, e.g. by redirecting the user to the login/home page. If you console.log the const verifiedJWT
you should see the decoded token showing the payload, the protectedHeader and the key. Inside the key, you should be able to see a “true” if it’s verified.
middleware.tsx
file:
Login
page to subscribe to the events of the Hanko client and redirect to the Todo
page after a successful login:
prisma schema
:
api/todo/route.tsx
file to get the user ID from the token, then create a new todo if there is a user ID:
todo/page.tsx
: