Firebase
는 Google이 제공하는 애플리케이션 개발 플랫폼이다.
개발자가 고품질의 애플리케이션을 빠르고 쉽게 구축할 수 있도록 돕는 다양한 도구와 서비스를 제공한다.
Firebase는 백엔드 서비스, 데이터베이스, 인증, 호스팅 등을 포함해서 애플리케이션의 전반적인 개발, 출시 운영을 지원하는 포괄적인 솔루션을 제공
Firebase Authentication
→ 지금 쓸 거간편한 Firebase 서비스를 활용해서 사용자 인증 과정을 구현해보자.
위에 과정을 거치기로 했다.
onIdTokenChanged()
를 사용해 토큰이 갱신되면 자동으로 업데이트 해준다.Project에서 Authentication 설정에서 Sign-in providers
에 Email/Password 방식을 사용 설정해준다.
Project Setting에 General에 아랫 쪽 App 부분에서 SDK setup and configuration
를 확인해준다.
그 파일을 복사해서 firebase.ts
로 프로젝트에 넣어준다.
// firebase.ts
import { initializeApp } from 'firebase/app';
import { getAuth } from 'firebase/auth';
const firebaseConfig = {
apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY,
authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID,
storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID,
measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID,
};
const app = initializeApp(firebaseConfig);
export const auth = getAuth(app);
나는 조금 변형해서 config 값들을 env에 넣어줬고, 인증 때 사용하기 위한 auth
을 export해줬다.
token을 쿠키에 관리하는 로직
// tokenManager.ts
import { deleteCookie, setCookie } from 'cookies-next';
import { NextOrObserver, User, onIdTokenChanged } from 'firebase/auth';
import { auth } from 'firebase';
export const TOKEN_COOKIE_NAME = 'idToken' as const;
export const TOKEN_COOKIE_OPTIONS: OptionsType = {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
maxAge: 60 * 60,
sameSite: 'strict',
} as const;
// 리스너가 여러 개 등록이 되는 일이 없도록...
let unsubscribeTokenChangedListener: (() => void) | undefined;
const saveIdToken = async (user: User | null) =>
user && setCookie(TOKEN_COOKIE_NAME, await user.getIdToken(), TOKEN_COOKIE_OPTIONS);
export async function sessionLogin(user: User) {
await saveIdToken(user);
unsubscribeTokenChangedListener?.();
unsubscribeTokenChangedListener = onIdTokenChanged(auth, saveIdToken as NextOrObserver<User>);
}
export async function sessionLogout() {
await auth.signOut();
unsubscribeTokenChangedListener?.();
deleteCookie(TOKEN_COOKIE_NAME);
}
firebase를 활용해 인증하는 API (예외 처리는 다음에)
import { deleteCookie, setCookie } from 'cookies-next';
import {
browserLocalPersistence,
browserSessionPersistence,
createUserWithEmailAndPassword,
sendEmailVerification,
setPersistence,
signInWithEmailAndPassword,
} from 'firebase/auth';
import { auth } from '@/shard/lib/firebase';
import handleFirebaseAuthError from '@/shard/lib/firebase.errorhandle';
import { sessionLogin, sessionLogout } from 'tokenManager';
export type AuthDTO = {
email: string;
password: string;
};
export async function signup({ email, password }: AuthDTO) {
const { user } = await createUserWithEmailAndPassword(auth, email, password);
await sessionLogin(user);
sendEmailVerification(user);
}
export async function login({ email, password }: AuthDTO) {
const { user } = await signInWithEmailAndPassword(auth, email, password);
await sessionLogin(user);
}
export async function logout() {
await sessionLogout();
}