Next.js / Supabase Auth

Supabase Auth

Хэрэглэгч бүртгүүлэх, нэвтрэх, гарах — дурын аппд байдаг боловч хэрэгжүүлэхэд цаг их зарцуулдаг хэсэг. Supabase Auth энэ бүгдийг бэлэн хэрэглүүрүүдээр хангадаг. Энэ хичээлд email/password нэвтрэлтийг бүрэн хэрэгжүүлнэ.

Бүртгэх — register

Server Action ашиглан шинэ хэрэглэгч үүсгэнэ:

typescript
// app/actions.ts (auth хэсэг)
"use server";

import { createClient } from "@/lib/supabase/server";
import { redirect } from "next/navigation";

export async function register(formData: FormData) {
  const email = formData.get("email") as string;
  const password = formData.get("password") as string;

  const supabase = await createClient();

  const { error } = await supabase.auth.signUp({ email, password });

  if (error) {
    throw new Error("Бүртгэлд алдаа гарлаа: " + error.message);
  }

  redirect("/courses");
}
tsx
// app/(auth)/register/page.tsx
import { register } from "@/app/actions";

export default function RegisterPage() {
  return (
    <main>
      <h1>Бүртгүүлэх</h1>
      <form action={register}>
        <label>
          И-мэйл
          <input type="email" name="email" required />
        </label>
        <label>
          Нууц үг
          <input type="password" name="password" required minLength={6} />
        </label>
        <button type="submit">Бүртгүүлэх</button>
      </form>
    </main>
  );
}

Нэвтрэх ба гарах — login / logout

typescript
// app/actions.ts
"use server";

import { createClient } from "@/lib/supabase/server";
import { redirect } from "next/navigation";

export async function login(formData: FormData) {
  const email = formData.get("email") as string;
  const password = formData.get("password") as string;

  const supabase = await createClient();

  const { error } = await supabase.auth.signInWithPassword({ email, password });

  if (error) {
    throw new Error(
      "Нэвтрэхэд алдаа гарлаа. И-мэйл эсвэл нууц үгээ шалгана уу.",
    );
  }

  redirect("/courses");
}

export async function logout() {
  const supabase = await createClient();
  await supabase.auth.signOut();
  redirect("/login");
}

Нэвтрэх хуудас:

tsx
// app/(auth)/login/page.tsx
import { login } from "@/app/actions";

export default function LoginPage() {
  return (
    <main>
      <h1>Нэвтрэх</h1>
      <form action={login}>
        <label>
          И-мэйл
          <input type="email" name="email" required />
        </label>
        <label>
          Нууц үг
          <input type="password" name="password" required />
        </label>
        <button type="submit">Нэвтрэх</button>
      </form>
    </main>
  );
}

Session шалгах — хэрэглэгч мэдэх

Server Component дотор одоогийн хэрэглэгчийг авах:

typescript
// app/profile/page.tsx
import { createClient } from '@/lib/supabase/server';
import { redirect } from 'next/navigation';

export default async function ProfilePage() {
  const supabase = await createClient();

  const { data: { user } } = await supabase.auth.getUser();

  // нэвтрээгүй бол login хуудас руу шилжүүлнэ
  if (!user) {
    redirect('/login');
  }

  return (
    <main>
      <h1>Профайл</h1>
      <p>И-мэйл: {user.email}</p>
    </main>
  );
}

getUser() нь серверт Supabase-тэй холбогдож session-г баталгаажуулдаг — getSession() cookie-с зүгээр уншдаг тул аюулгүй байдлын хувьд getUser() нь илүү найдвартай.

tsx
// components/nav/Navbar.tsx
import { createClient } from "@/lib/supabase/server";
import { logout } from "@/app/actions";

export default async function Navbar() {
  const supabase = await createClient();
  const {
    data: { user },
  } = await supabase.auth.getUser();

  return (
    <nav>
      <a href="/courses">Сургалтууд</a>
      {user ? (
        <>
          <a href="/profile">Профайл</a>
          <form action={logout}>
            <button type="submit">Гарах</button>
          </form>
        </>
      ) : (
        <a href="/login">Нэвтрэх</a>
      )}
    </nav>
  );
}

Дараагийн хичээлд:

Supabase өгөгдлийн санг Next.js-тэй хэрхэн ашиглахыг судална. Өгөгдөл унших, нэмэх, шинэчлэх, устгах — бүрэн CRUD хийж сурна.