Supabase & Astro
Supabase est une alternative open source à Firebase. Elle fournit une base de données Postgres, l’authentification, des fonctions edge, des abonnements en temps réel et le stockage.
Initialisation de Supabase dans Astro
Titre de la section Initialisation de Supabase dans AstroPrérequis
Titre de la section Prérequis- Un projet Supabase. Si vous n’en avez pas, vous pouvez vous inscrire gratuitement sur supabase.com et créer un nouveau projet.
- Un projet Astro avec server-side rendering (SSR) activé.
- Les identifiants Supabase pour votre projet. Vous pouvez les trouver dans l’onglet Paramètres > API de votre projet Supabase.
SUPABASE_URL
: L’URL de votre projet Supabase.SUPABASE_ANON_KEY
: La clé anonyme de votre projet Supabase.
Ajouter les informations d’identification de Supabase
Titre de la section Ajouter les informations d’identification de SupabasePour ajouter vos identifiants Supabase à votre projet Astro, ajoutez ce qui suit à votre fichier .env
:
SUPABASE_URL=YOUR_SUPABASE_URLSUPABASE_ANON_KEY=YOUR_SUPABASE_ANON_KEY
Maintenant, ces variables d’environnement sont disponibles dans votre projet.
Si vous souhaitez avoir IntelliSense pour vos variables d’environnement, éditez ou créez le fichier env.d.ts
dans votre répertoire src/
et ajoutez ce qui suit :
interface ImportMetaEnv { readonly SUPABASE_URL: string readonly SUPABASE_ANON_KEY: string}
interface ImportMeta { readonly env: ImportMetaEnv}
En savoir plus sur les variables d’environnement et les fichiers .env
dans Astro.
Votre projet doit maintenant inclure ces fichiers :
Répertoiresrc/
- env.d.ts
- .env
- astro.config.mjs
- package.json
Installation des dépendances
Titre de la section Installation des dépendancesPour vous connecter à Supabase, vous devez installer @supabase/supabase-js
dans votre projet.
npm install @supabase/supabase-js
pnpm add @supabase/supabase-js
yarn add @supabase/supabase-js
Ensuite, créez un dossier nommé lib
dans votre répertoire src/
. C’est là que vous ajouterez votre client Supabase.
Dans supabase.ts
, ajoutez ce qui suit pour initialiser votre client Supabase :
import { createClient } from "@supabase/supabase-js";
export const supabase = createClient( import.meta.env.SUPABASE_URL, import.meta.env.SUPABASE_ANON_KEY,);
Votre projet doit maintenant inclure ces fichiers :
Répertoiresrc/
Répertoirelib/
- supabase.ts
- env.d.ts
- .env
- astro.config.mjs
- package.json
Ajouter l’authentification avec Supabase
Titre de la section Ajouter l’authentification avec SupabaseSupabase fournit l’authentification dès le départ. Elle supporte l’authentification par email/mot de passe et l’authentification OAuth avec de nombreux fournisseurs dont GitHub, Google, et plusieurs autres.
Prérequis
Titre de la section Prérequis- Un projet Astro initialisé avec Supabase.
- Un projet Supabase avec l’authentification email/mot de passe activée. Vous pouvez l’activer dans l’onglet Authentication > Providers de votre projet Supabase.
Créer des points d’accès au serveur d’authentification
Titre de la section Créer des points d’accès au serveur d’authentificationPour ajouter l’authentification à votre projet, vous devrez créer quelques points de terminaison de serveur. Ces points seront utilisés pour enregistrer, connecter et déconnecter les utilisateurs.
POST /api/auth/register
: pour enregistrer un nouvel utilisateur.POST /api/auth/signin
: pour enregistrer un utilisateur.GET /api/auth/signout
: pour déconnecter un utilisateur.
Créez ces points de terminaison dans le répertoire src/pages/api/auth
de votre projet. Votre projet devrait maintenant inclure ces nouveaux fichiers :
Répertoiresrc/
Répertoirelib/
- supabase.ts
Répertoirepages/
Répertoireapi/
Répertoireauth/
- signin.ts
- signout.ts
- register.ts
- env.d.ts
- .env
- astro.config.mjs
- package.json
register.ts
crée un nouvel utilisateur dans Supabase. Il accepte une requête POST
avec l’email et le mot de passe. Il utilise ensuite le SDK de Supabase pour créer un nouvel utilisateur.
import type { APIRoute } from "astro";import { supabase } from "../../../lib/supabase";
export const POST: APIRoute = async ({ request, redirect }) => { const formData = await request.formData(); const email = formData.get("email")?.toString(); const password = formData.get("password")?.toString();
if (!email || !password) { return new Response("Email and password are required", { status: 400 }); }
const { error } = await supabase.auth.signUp({ email, password, });
if (error) { return new Response(error.message, { status: 500 }); }
return redirect("/signin");};
signin.ts
crée un nouvel utilisateur dans Supabase. Il accepte une requête POST
avec l’email et le mot de passe. Il utilise ensuite le SDK de Supabase pour créer un nouvel utilisateur
import type { APIRoute } from "astro";import { supabase } from "../../../lib/supabase";
export const POST: APIRoute = async ({ request, cookies, redirect }) => { const formData = await request.formData(); const email = formData.get("email")?.toString(); const password = formData.get("password")?.toString();
if (!email || !password) { return new Response("Email and password are required", { status: 400 }); }
const { data, error } = await supabase.auth.signInWithPassword({ email, password, });
if (error) { return new Response(error.message, { status: 500 }); }
const { access_token, refresh_token } = data.session; cookies.set("sb-access-token", access_token, { path: "/", }); cookies.set("sb-refresh-token", refresh_token, { path: "/", }); return redirect("/dashboard");};
signout.ts
permet à un utilisateur de se déconnecter. Il accepte une requête GET
et supprime les jetons d’accès et de rafraîchissement de l’utilisateur.
import type { APIRoute } from "astro";
export const GET: APIRoute = async ({ cookies, redirect }) => { cookies.delete("sb-access-token", { path: "/" }); cookies.delete("sb-refresh-token", { path: "/" }); return redirect("/signin");};
Création des pages d’authentification
Titre de la section Création des pages d’authentificationMaintenant que vous avez créé vos points d’accès au serveur, créez les pages qui les utiliseront.
src/pages/register
: contient un formulaire pour enregistrer un nouvel utilisateur.src/pages/signin
: contient un formulaire pour enregistrer un utilisateur.src/pages/dashboard
: contient une page qui n’est accessible qu’aux utilisateurs authentifiés.
Créez ces pages dans le répertoire src/pages
. Votre projet devrait maintenant inclure ces nouveaux fichiers :
Répertoiresrc/
Répertoirelib/
- supabase.ts
Répertoirepages/
Répertoireapi/
Répertoireauth/
- signin.ts
- signout.ts
- register.ts
- register.astro
- signin.astro
- dashboard.astro
- env.d.ts
- .env
- astro.config.mjs
- package.json
register.astro
contient un formulaire pour enregistrer un nouvel utilisateur. Il accepte un email et un mot de passe et envoie une requête POST
à /api/auth/register
.
---import Layout from "../layouts/Layout.astro";---
<Layout title="S'enregistrer"> <h1>S'enregistrer</h1> <p>Vous avez déjà un compte ? <a href="/signin">Connexion</a></p> <form action="/api/auth/register" method="post"> <label for="email" for="email">Email</label> <input type="email" name="email" id="email" /> <label for="password">Mot de passe</label> <input type="password" name="password" id="password" /> <button type="submit">Se connecter</button> </form></Layout>
signin.astro
contient un formulaire permettant d’identifier un utilisateur. Il accepte un email et un mot de passe et envoie une requête POST
à /api/auth/signin
. Il vérifie également la présence des jetons d’accès et de rafraîchissement. S’ils sont présents, il redirige vers le tableau de bord.
---import Layout from "../layouts/Layout.astro";
const { cookies, redirect } = Astro;
const accessToken = cookies.get("sb-access-token");const refreshToken = cookies.get("sb-refresh-token");
if (accessToken && refreshToken) { return redirect("/dashboard");}---
<Layout title="Connexion"> <h1>Connexion</h1> <p>Nouveau par ici ? <a href="/register">Se créer un compte</a></p> <form action="/api/auth/signin" method="post"> <label for="email" for="email">Email</label> <input type="email" name="email" id="email" /> <label for="password">Mot de passe</label> <input type="password" name="password" id="password" /> <button type="submit">Se connecter</button> </form></Layout>
dashboard.astro
contient une page qui n’est accessible qu’aux utilisateurs authentifiés. Elle vérifie la présence des jetons d’accès et de rafraîchissement. S’ils ne sont pas présents, elle redirige vers la page de connexion.
---import Layout from "../layouts/Layout.astro";import { supabase } from "../lib/supabase";
const { cookies, redirect } = Astro;
const accessToken = cookies.get("sb-access-token");const refreshToken = cookies.get("sb-refresh-token");
if (!accessToken || !refreshToken) { return redirect("/signin");}
const { data, error } = await supabase.auth.setSession({ refresh_token: refreshToken.value, access_token: accessToken.value,});
if (error) { cookies.delete("sb-access-token", { path: "/", }); cookies.delete("sb-refresh-token", { path: "/", });
return redirect("/signin");}
const email = data?.user?.email;---<Layout title="dashboard"> <h1>Bienvenue {email}</h1> <p>Nous sommes heureux de vous voir ici.</p> <form action="/api/auth/signout"> <button type="submit">Se déconnecter</button> </form></Layout>
Ajouter l’authentification OAuth
Titre de la section Ajouter l’authentification OAuthPour ajouter l’authentification OAuth à votre projet, vous devez éditer votre client Supabase pour activer le flux d’authentification avec "pkce"
. Vous pouvez en savoir plus sur les flux d’authentification dans la documentation Supabase.
import { createClient } from "@supabase/supabase-js";
export const supabase = createClient( import.meta.env.SUPABASE_URL, import.meta.env.SUPABASE_ANON_KEY, { auth: { flowType: "pkce", }, },);
Ensuite, dans le tableau de bord de Supabase, activez le fournisseur OAuth que vous souhaitez utiliser. Vous pouvez trouver la liste des fournisseurs supportés dans l’onglet Authentication > Providers de votre projet Supabase.
L’exemple suivant utilise GitHub comme fournisseur OAuth. Pour connecter votre projet à GitHub, suivez les étapes de la documentation Supabase.
Ensuite, créez un nouveau point de terminaison serveur pour gérer le rappel OAuth dans src/pages/api/auth/callback.ts
. Ce point de terminaison sera utilisé pour échanger le code OAuth contre un jeton d’accès et de rafraîchissement.
import type { APIRoute } from "astro";import { supabase } from "../../../lib/supabase";
export const GET: APIRoute = async ({ url, cookies, redirect }) => { const authCode = url.searchParams.get("code");
if (!authCode) { return new Response("No code provided", { status: 400 }); }
const { data, error } = await supabase.auth.exchangeCodeForSession(authCode);
if (error) { return new Response(error.message, { status: 500 }); }
const { access_token, refresh_token } = data.session;
cookies.set("sb-access-token", access_token, { path: "/", }); cookies.set("sb-refresh-token", refresh_token, { path: "/", });
return redirect("/dashboard");};
Ensuite, modifiez la page de connexion pour inclure un nouveau bouton permettant de se connecter avec le fournisseur OAuth. Ce bouton doit envoyer une requête POST
à /api/auth/signin
avec le provider
fixé au nom du fournisseur OAuth.
---import Layout from "../layouts/Layout.astro";
const { cookies, redirect } = Astro;
const accessToken = cookies.get("sb-access-token");const refreshToken = cookies.get("sb-refresh-token");
if (accessToken && refreshToken) { return redirect("/dashboard");}---
<Layout title="Connexion"> <h1>Connexion</h1> <p>Nouveau par ici ? <a href="/register">Créer un compte</a></p> <form action="/api/auth/signin" method="post"> <label for="email" for="email">Email</label> <input type="email" name="email" id="email" /> <label for="password">Mot de passe</label> <input type="password" name="password" id="password" /> <button type="submit">Login</button> <button value="github" name="provider" type="submit">Se connecter avec GitHub</button> </form></Layout>
Enfin, modifiez le point de terminaison du serveur de connexion pour gérer le fournisseur OAuth. Si le provider
est présent, il redirigera vers le fournisseur OAuth. Sinon, il connectera l’utilisateur avec son email et son mot de passe.
import type { APIRoute } from "astro";import { supabase } from "../../../lib/supabase";import type { Provider } from "@supabase/supabase-js";
export const POST: APIRoute = async ({ request, cookies, redirect }) => { const formData = await request.formData(); const email = formData.get("email")?.toString(); const password = formData.get("password")?.toString(); const provider = formData.get("provider")?.toString();
const validProviders = ["google", "github", "discord"];
if (provider && validProviders.includes(provider)) { const { data, error } = await supabase.auth.signInWithOAuth({ provider: provider as Provider, options: { redirectTo: "http://localhost:4321/api/auth/callback" }, });
if (error) { return new Response(error.message, { status: 500 }); }
return redirect(data.url); }
if (!email || !password) { return new Response("L'adresse e-mail et le mot de passe sont nécessaires", { status: 400 }); }
const { data, error } = await supabase.auth.signInWithPassword({ email, password, });
if (error) { return new Response(error.message, { status: 500 }); }
const { access_token, refresh_token } = data.session; cookies.set("sb-access-token", access_token, { path: "/", }); cookies.set("sb-refresh-token", refresh_token, { path: "/", }); return redirect("/dashboard");};
Après avoir créé le point d’accès OAuth et modifié la page de connexion et le point d’accès au serveur, votre projet devrait avoir la structure de fichier suivante :
Répertoiresrc/
Répertoirelib/
- supabase.ts
Répertoirepages/
Répertoireapi/
Répertoireauth/
- signin.ts
- signout.ts
- register.ts
- callback.ts
- register.astro
- signin.astro
- dashboard.astro
- env.d.ts
- .env
- astro.config.mjs
- package.json
Ressources de la communauté
Titre de la section Ressources de la communauté- Entrer dans l’esprit des fêtes avec Astro, React et Supabase
- Démonstration d’authentification avec Astro et Supabase