122. Persisting the User Authentication
npm create vue@latest
사용자 인증을 웹 애플리케이션에 지속적으로 유지하는 방법에 대해 말해보겠습니다.
- 목적: Firebase를 활용하여 애플리케이션이 시작될 때 사용자가 로그인되었는지 확인하고, 사용자 인증 상태를 유지하는 것
- 애플리케이션 구조:
- App 컴포넌트는 루트 컴포넌트로 애플리케이션에서 가장 먼저 초기화된다.
- Pinia 패키지에서
mapReadableStore
함수와 사용자 스토어를 임포트하고, 계산된 객체 내에서 사용자 스토어의 상태를 매핑한다.
- 인증상태 확인:
- created 생명주기 함수 내에서 사용자가 로그인되었는지 확인한다.
- Firebase의 auth 서비스를 사용하여 현재 로그인한 사용자의 정보를 가져온다.
- 현재 사용자 정보가 null이 아닌 경우, 사용자 로그인 상태를 true로 설정한다.
- 테스트 및 확인 방법:
- 브라우저에서 애플리케이션을 열고 페이지를 새로고침하여 정상 작동 여부를 확인한다.
- 개발자 도구의 Pinia 탭에서 사용자 스토어의 상태를 확인한다.
- Firebase는 인덱스DB를 사용하여 로컬 스토리지에 사용자 인증 정보를 저장한다.
- 데이터 클리어 및 로그아웃 테스트:
- Firebase 로컬 스토리지에서 사용자 데이터를 제거하여 로그아웃 상태 테스트
- 데이터를 제거하고 페이지를 새로고침하여 사용자 스토어의 로그인 상태가 false로 설정됨을 확인한다.
결론적으로, Firebase를 사용하여 사용자의 로그인 상태를 애플리케이션에 지속적으로 유지하는 방법을 배웠으며, 이를 통해 사용자 인증을 보다 효과적으로 관리하는 방법을 이해했습니다.
다음엔 로그인 폼에 대해 다룰 예정입니다.
userLoggedIn: false
상태
Firebase에 회원 등록 성공 후 userLoggedIn: true
상태
Application 탭 IndexedDB > firebaseLocalStorageDb > firebaseLocalStorage 에 인증 토큰 저장됨
위와 같이 저장된 키 값들을 볼 수 있음
Storage > Clear site data 버튼 클릭하면 모든 스토리지의 데이터들이 삭제됨
위와 같이 삭제된 것을 확인할 수 있음
아래와 같이 수정하고나면, 새로고침해도 동기화가 잘된다.
위 스크린샷에서처럼 Application Storage의 Clear site data 버튼만 클릭안한다면 말이다.
src/App.vue
<script setup lang="ts">
import AppHeader from '@/components/AppHeader.vue'
import AppAuth from '@/components/AppAuth.vue'
import HelloWorld from '@/components/HelloWorld.vue'
import useUser from '@/stores/user'
import { auth } from '@/includes/firebase'
import { storeToRefs } from 'pinia'
const userStore = useUser()
const { userLoggedIn } = storeToRefs(userStore)
if (auth.currentUser) {
userLoggedIn.value = true
}
</script>
<template>
<AppHeader />
<!-- Introduction -->
<section class="mb-8 py-20 text-white text-center relative">
<div
class="absolute inset-0 w-full h-full bg-contain introduction-bg"
style="background-image: url('assets/img/header.png')"
></div>
<div class="container mx-auto">
<div class="text-white main-header-content">
<h1 class="font-bold text-5xl mb-5">Listen to Great Music!</h1>
<HelloWorld #default="{ user, favorites }">
<p>Hello {{ user.name }}. I like {{ favorites[0] }}</p>
</HelloWorld>
<p class="w-full md:w-8/12 mx-auto">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus et dolor mollis, congue
augue non, venenatis elit. Nunc justo eros, suscipit ac aliquet imperdiet, venenatis et
sapien. Duis sed magna pulvinar, fringilla lorem eget, ullamcorper urna.
</p>
</div>
</div>
<img
class="relative block mx-auto mt-5 -mb-20 w-auto max-w-full"
src="/assets/img/introduction-music.png"
/>
</section>
<!-- Main Content -->
<section class="container mx-auto">
<div class="bg-white rounded border border-gray-200 relative flex flex-col">
<div class="px-6 pt-6 pb-5 font-bold border-b border-gray-200">
<span class="card-title">Songs</span>
<!-- Icon -->
<i class="fa fa-headphones-alt float-right text-green-400 text-xl"></i>
</div>
<!-- Playlist -->
<ol id="playlist">
<li
class="flex justify-between items-center p-3 pl-6 cursor-pointer transition duration-300 hover:bg-gray-50"
>
<div>
<a href="#" class="font-bold block text-gray-600">Song Title</a>
<span class="text-gray-500 text-sm">Artist Name</span>
</div>
<div class="text-gray-600 text-lg">
<span class="comments">
<i class="fa fa-comments text-gray-600"></i>
15
</span>
</div>
</li>
<li
class="flex justify-between items-center p-3 pl-6 cursor-pointer transition duration-300 hover:bg-gray-50"
>
<div>
<a href="#" class="font-bold block text-gray-600">Song Title</a>
<span class="text-gray-500 text-sm">Artist Name</span>
</div>
<div class="text-gray-600 text-lg">
<span class="comments">
<i class="fa fa-comments text-gray-600"></i>
15
</span>
</div>
</li>
<li
class="flex justify-between items-center p-3 pl-6 cursor-pointer transition duration-300 hover:bg-gray-50"
>
<div>
<a href="#" class="font-bold block text-gray-600">Song Title</a>
<span class="text-gray-500 text-sm">Artist Name</span>
</div>
<div class="text-gray-600 text-lg">
<span class="comments">
<i class="fa fa-comments text-gray-600"></i>
15
</span>
</div>
</li>
<li
class="flex justify-between items-center p-3 pl-6 cursor-pointer transition duration-300 hover:bg-gray-50"
>
<div>
<a href="#" class="font-bold block text-gray-600">Song Title</a>
<span class="text-gray-500 text-sm">Artist Name</span>
</div>
<div class="text-gray-600 text-lg">
<span class="comments">
<i class="fa fa-comments text-gray-600"></i>
15
</span>
</div>
</li>
<li
class="flex justify-between items-center p-3 pl-6 cursor-pointer transition duration-300 hover:bg-gray-50"
>
<div>
<a href="#" class="font-bold block text-gray-600">Song Title</a>
<span class="text-gray-500 text-sm">Artist Name</span>
</div>
<div class="text-gray-600 text-lg">
<span class="comments">
<i class="fa fa-comments text-gray-600"></i>
15
</span>
</div>
</li>
<li
class="flex justify-between items-center p-3 pl-6 cursor-pointer transition duration-300 hover:bg-gray-50"
>
<div>
<a href="#" class="font-bold block text-gray-600">Song Title</a>
<span class="text-gray-500 text-sm">Artist Name</span>
</div>
<div class="text-gray-600 text-lg">
<span class="comments">
<i class="fa fa-comments text-gray-600"></i>
15
</span>
</div>
</li>
<li
class="flex justify-between items-center p-3 pl-6 cursor-pointer transition duration-300 hover:bg-gray-50"
>
<div>
<a href="#" class="font-bold block text-gray-600">Song Title</a>
<span class="text-gray-500 text-sm">Artist Name</span>
</div>
<div class="text-gray-600 text-lg">
<span class="comments">
<i class="fa fa-comments text-gray-600"></i>
15
</span>
</div>
</li>
<li
class="flex justify-between items-center p-3 pl-6 cursor-pointer transition duration-300 hover:bg-gray-50"
>
<div>
<a href="#" class="font-bold block text-gray-600">Song Title</a>
<span class="text-gray-500 text-sm">Artist Name</span>
</div>
<div class="text-gray-600 text-lg">
<span class="comments">
<i class="fa fa-comments text-gray-600"></i>
15
</span>
</div>
</li>
<li
class="flex justify-between items-center p-3 pl-6 cursor-pointer transition duration-300 hover:bg-gray-50"
>
<div>
<a href="#" class="font-bold block text-gray-600">Song Title</a>
<span class="text-gray-500 text-sm">Artist Name</span>
</div>
<div class="text-gray-600 text-lg">
<span class="comments">
<i class="fa fa-comments text-gray-600"></i>
15
</span>
</div>
</li>
<li
class="flex justify-between items-center p-3 pl-6 cursor-pointer transition duration-300 hover:bg-gray-50"
>
<div>
<a href="#" class="font-bold block text-gray-600">Song Title</a>
<span class="text-gray-500 text-sm">Artist Name</span>
</div>
<div class="text-gray-600 text-lg">
<span class="comments">
<i class="fa fa-comments text-gray-600"></i>
15
</span>
</div>
</li>
<li
class="flex justify-between items-center p-3 pl-6 cursor-pointer transition duration-300 hover:bg-gray-50"
>
<div>
<a href="#" class="font-bold block text-gray-600">Song Title</a>
<span class="text-gray-500 text-sm">Artist Name</span>
</div>
<div class="text-gray-600 text-lg">
<span class="comments">
<i class="fa fa-comments text-gray-600"></i>
15
</span>
</div>
</li>
<li
class="flex justify-between items-center p-3 pl-6 cursor-pointer transition duration-300 hover:bg-gray-50"
>
<div>
<a href="#" class="font-bold block text-gray-600">Song Title</a>
<span class="text-gray-500 text-sm">Artist Name</span>
</div>
<div class="text-gray-600 text-lg">
<span class="comments">
<i class="fa fa-comments text-gray-600"></i>
15
</span>
</div>
</li>
<li
class="flex justify-between items-center p-3 pl-6 cursor-pointer transition duration-300 hover:bg-gray-50"
>
<div>
<a href="#" class="font-bold block text-gray-600">Song Title</a>
<span class="text-gray-500 text-sm">Artist Name</span>
</div>
<div class="text-gray-600 text-lg">
<span class="comments">
<i class="fa fa-comments text-gray-600"></i>
15
</span>
</div>
</li>
</ol>
<!-- .. end Playlist -->
</div>
</section>
<!-- Player -->
<div class="fixed bottom-0 left-0 bg-white px-4 py-2 w-full">
<!-- Track Info -->
<div class="text-center">
<span class="song-title font-bold">Song Title</span> by
<span class="song-artist">Artist</span>
</div>
<div class="flex flex-nowrap gap-4 items-center">
<!-- Play/Pause Button -->
<button type="button">
<i class="fa fa-play text-gray-500 text-xl"></i>
</button>
<!-- Current Position -->
<div class="player-currenttime">00:00</div>
<!-- Scrub Container -->
<div class="w-full h-2 rounded bg-gray-200 relative cursor-pointer">
<!-- Player Ball -->
<span class="absolute -top-2.5 -ml-2.5 text-gray-800 text-lg" style="left: 50%">
<i class="fas fa-circle"></i>
</span>
<!-- Player Progress Bar-->
<span
class="block h-2 rounded bg-gradient-to-r from-green-500 to-green-400"
style="width: 50%"
></span>
</div>
<!-- Duration -->
<div class="player-duration">03:06</div>
</div>
</div>
<AppAuth />
</template>