>  기사  >  웹 프론트엔드  >  Nuxt v3를 사용하여 Supabase Auth 설정

Nuxt v3를 사용하여 Supabase Auth 설정

Barbara Streisand
Barbara Streisand원래의
2024-10-17 08:24:03682검색

인증 구현은 대부분의 프로젝트에서 수행하는 작업이지만 실제로 수행하는 빈도 때문에 기억으로 수행하는 방법을 기억하지 못할 수도 있습니다.

다음은 Nuxt v3로 Supabase Auth를 구현하는 방법에 대한 빠른 방법입니다. 이 예에서는 OTP를 사용하지만 모든 경우에 적용됩니다.

먼저 Supabase 웹사이트로 이동하여 프로젝트를 시작하세요.

Supabase에서 프로젝트를 생성하고 Nuxt에서 프로젝트를 시작한 후 다음을 수행하여 Supabase Nuxt 패키지를 설치하려고 합니다.

npx nuxi@latest 모듈에 supabase 추가

그런 다음 .env 파일을 생성하고 다음 환경 변수를 추가합니다.

SUPABASE_URL=<your_supabase_url>
SUPABASE_KEY=<your_supabase_key>

프로젝트에 대한 Supabase 대시보드의 설정 -> API

Setting up Supabase Auth with Nuxt v3

이후에는 프로젝트를 설정할 수 있습니다. 지금까지 매우 기본적인 파일 2개를 만들었습니다:

  1. auth.ts (피니아 스토어를 이용했는데 일반 파일만 사용해도 무방합니다)
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>

오류가 발생할 경우를 대비해 저는 NuxtUI도 사용하고 있습니다.

기본적으로 signInWithOtp 기능은 매직 링크를 보내기 때문에 토큰을 보내려면 Supabase 대시보드에서 이메일 템플릿을 변경해야 합니다.

Setting up Supabase Auth with Nuxt v3
이는 인증 -> 아래에 있습니다. 이메일 템플릿 -> {{ .Token }}

을 사용하도록 가입 확인 및 매직 링크 템플릿을 변경하세요.

이제 거의 모든 것입니다. 실제 인증을 받았습니다!
로그아웃을 추가하려면 다음과 같이 이전 파일에 메소드를 추가할 수도 있습니다.

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

  if (error) {
    throw error;
  }

  return true;
};

그러나 특정 경로를 보호하려는 경우 미들웨어를 추가할 수도 있습니다.

루트에 middleware(이름은 키)라는 폴더와 auth.ts라는 파일을 만듭니다.

그런 다음 다음과 같은 내용을 추가할 수 있습니다.

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("/");
  }
});

이것은 기본적으로 /app 경로를 서버로부터 보호하므로 로그인하지 않고 /app으로 이동하려고 하면 /auth로 리디렉션됩니다.

마찬가지로 이미 로그인한 상태에서 /auth를 방문하려고 하면 홈 페이지 /로 리디렉션됩니다.

이제 이를 사용하려면