
⏲ How to add authentication to your Astro site
Auth-astro package
To add Auth to my Astro application, I used the package "auth-astro". Which provides auth.js for Astro. There is currently also a pull request which merges the "auth-astro" package into auth.js.
Adding the package
To add the package, you can use the astro cli like this.
If you are using pnpm you also need to install the cookie package:
pnpm i cookie
npm run astro add auth-astro
or install the needed packages manually:
npm install auth-astro@latest @auth/core@latest
Configuration
To configure the package, you need to edit the astro config called "astro.config.mjs" in the root of your project. As you can see in the example below (line 14 to 21), you need to add the auth function to the integrations array. You also need to add the auth provider you want to use. In this example I used Google. You can find more providers here.
import { defineConfig } from 'astro/config';
import tailwind from "@astrojs/tailwind";
import vercel from "@astrojs/vercel/serverless";
import partytown from "@astrojs/partytown";
import { loadEnv } from 'vite';
import auth from 'auth-astro'
import Google from "@auth/core/providers/google"
const env = loadEnv('production', process.cwd(), '');
// https://astro.build/config
export default defineConfig({
integrations: [tailwind(), partytown(),
auth({
providers: [
Google({
clientId: env.GOOGLE_ID,
clientSecret: env.GOOGLE_SECRET
})
]
})
],
output: "server",
adapter: vercel({
analytics: true
})
});
Setup Environment Variables
To setup the environment variables, you need to create a ".env" file in the root of your project and add the following variables:
AUTH_SECRET=<auth-secret>
AUTH_TRUST_HOST=true
GOOGLE_SECRET=<google-secret>
GOOGLE_ID=<google-id>
for the AUTH_SECRET
you can use the following command to generate a random secret or use this site https://randomkeygen.com/
openssl rand -hex 32
Creating the login page
Here is an example of a login page:
import Layout from "../../layouts/Layout.astro";
import { authOpts } from "src/pages/api/auth/[...astroAuth]";
import { Icon } from "astro-icon";
---
<Layout title="Login">
<main class="flex flex-col gap-4 items-center justify-center h-screen">
<div
class="flex flex-col gap-2 rounded-xl overflow-hidden font-sans border-2 border-base-neutral p-4"
>
<button id="google" class="btn">
<span class="flex gap-2">
<Icon class="w-4 h-4" name="mdi:google" />
Login with Google
</span>
</button>
</div>
</main>
</Layout>
<script>
const { signIn } = await import("auth-astro/client");
const google = document.getElementById("google");
google.addEventListener("click", () => {
signIn("google");
});
</script>
Check if a user is logged in
To check if the user is logged in, you can use the following code:
---
import { getSession } from "auth-astro/server";
let session = await getSession(Astro.request);
if (!session) {
return Astro.redirect("/login");
}
---
<div>
<h1>Protected Page</h1>
<p>Hi {{session.user.name}, only logged in users can see this page</p>
</div>
If the user is not logged in, he will be redirected to the login page using the Astros redirect utility function. You can find more information about the redirect function here.import BlogPostHeader from "@/components/blog/blog-post-header";