세션 및 인증
인증은 웹 앱에서 매우 일반적인 요구 사항입니다. 이 레시피에서는 Nuxt 앱에서 기본 사용자 등록 및 인증을 구현하는 방법을 보여줍니다.
소개
이 레시피에서는 클라이언트 측 및 서버 측 세션 데이터를 관리하기 위한 편리한 유틸리티를 제공하는 Nuxt Auth Utils를 사용하여 풀스택 Nuxt 앱에서 인증을 설정합니다.
이 모듈은 보안 및 봉인된 쿠키를 사용하여 세션 데이터를 저장하므로 세션 데이터를 저장하기 위해 데이터베이스를 설정할 필요가 없습니다.
nuxt-auth-utils 설치
nuxt
CLI를 사용하여 nuxt-auth-utils
모듈을 설치합니다.
npx nuxt module add auth-utils
이 명령은 nuxt-auth-utils
를 종속성으로 설치하고 nuxt.config.ts
의 modules
섹션에 추가합니다.
쿠키 암호화 키
nuxt-auth-utils
는 봉인된 쿠키를 사용하여 세션 데이터를 저장하므로, 세션 쿠키는 NUXT_SESSION_PASSWORD
환경 변수의 비밀 키를 사용하여 암호화됩니다.
설정되지 않은 경우, 이 환경 변수는 개발 모드에서 실행할 때 자동으로 .env
에 추가됩니다.
NUXT_SESSION_PASSWORD=a-random-password-with-at-least-32-characters
배포하기 전에 이 환경 변수를 프로덕션 환경에 추가해야 합니다.
로그인 API 경로
이 레시피에서는 정적 데이터를 기반으로 사용자를 로그인시키는 간단한 API 경로를 만듭니다.
이메일과 비밀번호를 요청 본문에 포함한 POST 요청을 수락하는 /api/login
API 경로를 만듭니다.
import { z } from 'zod'
const bodySchema = z.object({
email: z.string().email(),
password: z.string().min(8)
})
export default defineEventHandler(async (event) => {
const { email, password } = await readValidatedBody(event, bodySchema.parse)
if (email === 'admin@admin.com' && password === 'iamtheadmin') {
// 쿠키에 사용자 세션 설정
// 이 서버 유틸리티는 auth-utils 모듈에 의해 자동으로 가져옵니다
await setUserSession(event, {
user: {
name: 'John Doe'
}
})
return {}
}
throw createError({
statusCode: 401,
message: '잘못된 자격 증명'
})
})
프로젝트에 zod
종속성을 설치해야 합니다 (npm i zod
).
nuxt-auth-utils
에서 제공하는 setUserSession
서버 헬퍼에 대해 더 읽어보세요.
로그인 페이지
이 모듈은 애플리케이션에서 사용자가 인증되었는지 확인할 수 있는 Vue composable을 제공합니다:
const { loggedIn, session, user, clear, fetch } = useUserSession()
로그인 데이터를 /api/login
경로로 제출하는 폼이 있는 로그인 페이지를 만듭니다.
<script setup lang="ts">
const { loggedIn, user, fetch: refreshSession } = useUserSession()
const credentials = reactive({
email: '',
password: '',
})
async function login() {
$fetch('/api/login', {
method: 'POST',
body: credentials
})
.then(async () => {
// 클라이언트 측에서 세션을 새로고침하고 홈 페이지로 리디렉션
await refreshSession()
await navigateTo('/')
})
.catch(() => alert('잘못된 자격 증명'))
}
</script>
<template>
<form @submit.prevent="login">
<input v-model="credentials.email" type="email" placeholder="Email" />
<input v-model="credentials.password" type="password" placeholder="Password" />
<button type="submit">Login</button>
</form>
</template>
API 경로 보호
서버 경로를 보호하는 것은 데이터를 안전하게 유지하는 데 중요합니다. 클라이언트 측 미들웨어는 사용자에게 유용하지만, 서버 측 보호 없이는 데이터에 여전히 접근할 수 있습니다. 민감한 데이터가 있는 경로는 반드시 보호해야 하며, 사용자가 로그인하지 않은 경우 401 오류를 반환해야 합니다.
auth-utils
모듈은 사용자가 로그인하고 활성 세션을 가지고 있는지 확인하는 데 도움이 되는 requireUserSession
유틸리티 함수를 제공합니다.
인증된 사용자만 접근할 수 있는 /api/user/stats
경로의 예를 만들어 보겠습니다.
export default defineEventHandler(async (event) => {
// 사용자가 로그인했는지 확인
// 유효한 사용자 세션에서 요청이 오지 않으면 401 오류를 발생시킵니다
const { user } = await requireUserSession(event)
// TODO: 사용자 기반의 통계를 가져옵니다
return {}
});
앱 경로 보호
서버 측 경로가 있는 상태에서 데이터는 안전하지만, 추가 조치를 취하지 않으면 인증되지 않은 사용자가 /users
페이지에 접근할 때 이상한 데이터를 얻을 수 있습니다. 클라이언트 측에서 경로를 보호하고 사용자를 로그인 페이지로 리디렉션하기 위해 클라이언트 측 미들웨어를 만들어야 합니다.
nuxt-auth-utils
는 사용자가 로그인했는지 확인하고 로그인하지 않은 경우 리디렉션하는 데 사용할 수 있는 편리한 useUserSession
composable을 제공합니다.
/middleware
디렉토리에 미들웨어를 만듭니다. 서버와 달리 클라이언트 측 미들웨어는 모든 엔드포인트에 자동으로 적용되지 않으며, 적용할 위치를 지정해야 합니다.
export default defineNuxtRouteMiddleware(() => {
const { loggedIn } = useUserSession()
// 인증되지 않은 경우 사용자를 로그인 화면으로 리디렉션
if (!loggedIn.value) {
return navigateTo('/login')
}
})
홈 페이지
이제 경로를 보호하기 위한 앱 미들웨어가 있으므로, 인증된 사용자 정보를 표시하는 홈 페이지에서 사용할 수 있습니다. 사용자가 인증되지 않은 경우 로그인 페이지로 리디렉션됩니다.
보호하려는 경로에 미들웨어를 적용하기 위해 definePageMeta
를 사용할 것입니다.
<script setup lang="ts">
definePageMeta({
middleware: ['authenticated'],
})
const { user, clear: clearSession } = useUserSession()
async function logout() {
await clearSession()
await navigateTo('/login')
}
</script>
<template>
<div>
<h1>환영합니다 {{ user.name }}</h1>
<button @click="logout">로그아웃</button>
</div>
</template>
세션을 지우고 사용자를 로그인 페이지로 리디렉션하는 로그아웃 버튼도 추가했습니다.
결론
Nuxt 앱에서 매우 기본적인 사용자 인증 및 세션 관리를 성공적으로 설정했습니다. 또한 서버 및 클라이언트 측에서 민감한 경로를 보호하여 인증된 사용자만 접근할 수 있도록 했습니다.
다음 단계로는:
- 20개 이상의 지원되는 OAuth 제공자를 사용하여 인증 추가
- 사용자를 저장하기 위한 데이터베이스 추가, Nitro SQL Database 또는 NuxtHub SQL Database 참조
- 비밀번호 해싱을 사용하여 이메일 및 비밀번호로 사용자 가입 허용
- WebAuthn / Passkeys 지원 추가
OAuth 인증, 데이터베이스 및 CRUD 작업이 포함된 Nuxt 앱의 전체 예제를 보려면 오픈 소스 atidone 저장소를 확인하세요.
※이 페이지는 Nuxt.js 공식 문서의 비공식 번역 페이지입니다.
공식 문서의 해당 페이지는 여기 있습니다:
https://nuxt.com/docs/3.x/guide/recipes/sessions-and-authentication