Setting up authentication in Astro with Prisma and Planetscale
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.