Rumah  >  Artikel  >  hujung hadapan web  >  Menyediakan Supabase Auth dengan Nuxt v3

Menyediakan Supabase Auth dengan Nuxt v3

Barbara Streisand
Barbara Streisandasal
2024-10-17 08:24:03687semak imbas

Melaksanakan pengesahan ialah sesuatu yang anda lakukan pada kebanyakan projek, tetapi masih sesuatu yang anda mungkin tidak ingat cara melakukannya mengikut ingatan kerana kekerapan anda sebenarnya melakukannya.

Berikut ialah cara cepat tentang melaksanakan Supabase Auth dengan Nuxt v3. Dalam contoh ini, kami akan menggunakan OTP, tetapi ia digunakan untuk setiap kes.

Anda mula-mula ingin memulakan projek anda dengan pergi ke tapak web Supabase.

Selepas mencipta projek dalam Supabase dan memulakan projek anda pada Nuxt, kami mahu memasang pakej Supabase Nuxt dengan melakukan:

npx nuxi@modul terkini tambah supabase

Kami kemudiannya akan mencipta fail .env kami dan menambah pembolehubah persekitaran berikut:

SUPABASE_URL=<your_supabase_url>
SUPABASE_KEY=<your_supabase_key>

Anda boleh menemui ini pada papan pemuka Supabase untuk projek anda, di bawah Tetapan -> API

Setting up Supabase Auth with Nuxt v3

Selepas itu, kami boleh menyediakan projek kami. Saya telah membuat 2 fail yang sangat asas setakat ini:

  1. auth.ts (Saya menggunakan kedai Pinia, tetapi jangan ragu untuk menggunakan hanya fail biasa)
import { defineStore } from "pinia";

export const useAuthStore = defineStore("auth", () => {
  const supabase = useSupabaseClient();

  const sendOtp = async (email: string) => {
    const { error } = await supabase.auth.signInWithOtp({
      email,
    });

    if (error) {
      throw error;
    }

    return true;
  };

  const verifyOtp = async (email: string, otp: string) => {
    const { error } = await supabase.auth.verifyOtp({
      type: "email",
      token: otp,
      email,
    });

    if (error) {
      throw error;
    }

    return true;
  };

  return {
    sendOtp,
    verifyOtp,
  };
});
  1. LoginForm.vue
<template>
  <div class="max-w-md mx-auto bg-white p-8 rounded-lg shadow-md">
    <h2 class="text-3xl font-bold mb-6 text-center text-gray-800">Welcome</h2>
    <form @submit.prevent="handleSubmit" class="space-y-6">
      <div v-if="mode === 'email'">
        <label for="email" class="block mb-2 font-medium text-gray-700"
          >Email</label
        >
        <input
          type="email"
          id="email"
          v-model="email"
          required
          placeholder="Enter your email"
          class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 transition duration-200"
        />
      </div>

      <div v-else-if="mode === 'code'">
        <p class="mb-2 font-medium text-gray-700">
          Enter the 6-digit code sent to {{ email }}
        </p>
        <input
          type="text"
          v-model="otpCode"
          required
          placeholder="Enter 6-digit code"
          maxlength="6"
          class="w-full px-4 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 transition duration-200"
        />
      </div>

      <UButton
        icon="i-heroicons-paper-airplane"
        size="lg"
        color="primary"
        variant="solid"
        :label="buttonLabel"
        :trailing="true"
        block
      />
    </form>
  </div>
</template>

<script setup lang="ts">
import { ref, computed } from "vue";
import { useAuthStore } from "~/stores/auth";

const authStore = useAuthStore();

const email = ref("");
const otpCode = ref("");
const mode = ref("email");

const buttonLabel = computed(() => {
  return mode.value === "email" ? "Send One-Time Password" : "Verify Code";
});

const handleSubmit = async () => {
  if (mode.value === "email") {
    try {
      await authStore.sendOtp(email.value);
      mode.value = "code";
    } catch (error) {
      console.log("Error sending OTP: ", error);
    }
  } else {
    try {
      await authStore.verifyOtp(email.value, otpCode.value);
    } catch (error) {
      console.log("Error verifying OTP: ", error);
    }
  }
};
</script>

<style scoped></style>

Perhatikan bahawa saya juga menggunakan NuxtUI, sekiranya anda mendapat sebarang ralat.

Oleh kerana secara lalai, fungsi signInWithOtp menghantar pautan ajaib, anda perlu menukar templat e-mel pada papan pemuka Supabase untuk menghantar token:

Setting up Supabase Auth with Nuxt v3
Ini ditemui di bawah Pengesahan -> Templat E-mel -> Tukar templat Confirm Signup dan Magic Link untuk menggunakan {{ .Token }}

Dan begitulah, anda mempunyai pengesahan yang berfungsi!
Jika anda ingin menambah log keluar, anda juga boleh menambah kaedah pada fail anda yang terdahulu seperti:

const signOut = async () => {
  const { error } = await supabase.auth.signOut();

  if (error) {
    throw error;
  }

  return true;
};

Walau bagaimanapun, jika anda ingin melindungi laluan tertentu, kami juga boleh melakukannya dengan menambah perisian tengah.

Buat folder pada akar dipanggil middleware (nama ialah kunci) dan fail dipanggil auth.ts.

Anda kemudian boleh menambah sesuatu seperti ini:

export default defineNuxtRouteMiddleware((to) => {
  const user = useSupabaseUser();

  const protectedRoutes = ["/app"];

  if (!user.value && protectedRoutes.includes(to.path)) {
    return navigateTo("/auth");
  }

  if (user.value && to.path === "/auth") {
    return navigateTo("/");
  }
});

Ini pada asasnya akan melindungi daripada pelayan laluan /app anda, jadi jika anda cuba pergi ke /app tanpa dilog masuk, anda akan diubah hala ke /auth.

Begitu juga, jika anda cuba melawat /auth semasa sedang dilog masuk, anda akan dialihkan ke halaman utama /.

Sekarang, untuk menggunakan ini, anda boleh meletakkannya di dalam tag mana-mana komponen anda seperti ini:

<script setup lang="ts">
definePageMeta({
  middleware: "auth", // this is the name of the file, minus the extension
});
</script>

Dan itu sahaja, semudah itu!

Atas ialah kandungan terperinci Menyediakan Supabase Auth dengan Nuxt v3. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn