Saltar al contenido principal

Firebase Auth

Firebase

  1. Crear proyecto
  2. Agregar app web al proyecto
  3. Instalar dependencia firebase
  4. Crear archivo de configuración. Las llaves no son privadas, ya que viajan al cliente.
src\firebase\config.ts
import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth";

// Your web app's Firebase configuration
const firebaseConfig = {
  apiKey: "",
  authDomain: "",
  projectId: "",
  storageBucket: "",
  messagingSenderId: "",
  appId: "",
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
// Get the Auth service for the default app
const auth = getAuth(app);

auth.languageCode = "es";

export const firebase = {
  app,
  auth,
};

Actions

  1. Register
  2. Login (correo y contraseña)
  3. Login (Google)
  4. Logout

Form

Middleware

  • Función que se ejecuta o llama cada vez que se renderiza una página o endpoint
  • Se ejecuta antes de mostrar o renderizar la página o ruta
  • Solo se ejecutan en el servidor
  • Se tiene acceso a Cookies y Request, con lo que se pueden hacer verificaciones
  • context.locals es información que pasa entre pantallas, como la información de la sesión de un usuario autenticado
  • El archivo debe llamarse src/middleware.ts o src/middleware/index.ts
  • Se pueden verificar o añadir roles que viajen a través de toda la request
src\middleware.ts
import { defineMiddleware } from "astro:middleware";
import { firebase } from "./firebase/config";

const privateRoutes = ["/protected"];
const noAuthRequired = ["/auth/login", "/auth/register"];

export const onRequest = defineMiddleware(({ url, locals, redirect }, next) => {
  const isLoggedIn = !!firebase.auth.currentUser;
  const user = firebase.auth.currentUser;

  // Add information to locals (context)
  locals.isLoggedIn = isLoggedIn;
  if (user) {
    locals.user = {
      name: user.displayName!,
      email: user.email!,
      emailVerified: user.emailVerified,
      avatar: user.photoURL ?? "",
    };
  }

  // If the user is not logged in and tries to access a private route
  // redirect to the login page
  if (!isLoggedIn && privateRoutes.includes(url.pathname)) {
    return redirect("/auth/login");
  }

  // If the user is logged in and tries to access a public route
  // redirect to the home page
  if (isLoggedIn && noAuthRequired.includes(url.pathname)) {
    return redirect("/");
  }

  return next();
});

env.d.ts

src\env.d.ts
interface User {
  email: string;
  name: string;
  avatar: string;
  emailVerified: boolean;
}

declare namespace App {
  interface Locals {
    isLoggedIn: boolean;
    user: User | null;
  }
}

Protected page

src\pages\protected.astro
---
import { firebase } from "@/firebase/config";
import MainLayout from "@/layouts/MainLayout.astro";

// Protected route with middleware
const { user, isLoggedIn } = Astro.locals;

//if (!isLoggedIn || !user) return Astro.redirect("/auth/login");
const { name, email, avatar } = user!;

const firebaseUser = firebase.auth.currentUser;
// Manual protected route and user extract details (without middleware)
//if (firebaseUser === null) return Astro.redirect("/auth/login");

await firebaseUser?.reload();
const { emailVerified } = firebaseUser!;

//const { displayName, email, emailVerified, photoURL } = firebaseUser;
//const name = displayName ?? "No name";
---

<MainLayout>
</MainLayout>