I’ve been wanting to add authentication to my personal website for a while now to see how it works in Astro.
With Prisma and PlanetScale already running for comments on my blogs, I decided to store my account information in PlanetScale.
Because it’s just used for my own account, and I’m not storing any other sensitive information in my database, I decided to store the credentials in plain text for now.
I changed my Prisma schema to make this possible:
Once the model is updated in the code, running npx prisma db push propagates the changes to PlanetScale, so the schema is updated in the actual database.
I used an existing package called @astro-auth to handle all the authentication on my site.
For this to work, I needed to add 2 environment variables to my application: ASTROAUTH_URL (the URL my site is hosted on) and ASTROAUTH_SECRET (a self chosen secret key).
Because I stored the credentials in PlanetScale, I needed to use the CredentialProvider to enable logging in with username and password.
There are many other providers available on @astro-auth, go check out the package if you’re interested.
The code needed to set this up with @astro-auth looks like this:
Creating a login page was very easy.
I just created a form, calling the signIn() method from @astro-auth on submit, and BOOM: logged in!
The code for the login page:
After submitting the form, the user’s signed in and is redirected to the homepage.
Protecting a page with authentication is easy, just checking the logged in user with the getUser() function from @astro-auth.
Here’s an example of a page where I used this check:
If the user is not logged in, the user will be redirected to the homepage with a 307 status code.
I also have an API route to delete comments on my blog posts, which I want to fence off so only authenticated user can use this API.
It’s possible to use the getUser() function from @astro-auth for this too, but this time we’re going to pass the request instead of the Astro object.
Example of using this code:
So when the user is not authenticated, a 403 response will be returned.
Hope this was helpful!
Source code can be found on my Github as always.
Did you like this post? Check out my latest blog posts: