본문 바로가기

백엔드/파이어베이스

파이어베이스 (인증) - 이메일, 비밀번호

반응형

백엔드 통합서비스인 파이어베이스에서 제공하는 많은 기능 중 인증기능을 살펴볼까 합니다. 파이어베이스 인증 서비스의 가장 큰 장점은 브라우저에서 로그인 한 사용자의 상태유지 기능을 기본적으로 제공하므로 일반 서버를 통해 만드는 경우 처럼 상태유지를 위해 제이슨 토큰 등을 생성하여 주고받을 필요가 없다는 점입니다.

목차

파이어베이스에서 서비스 설정하기

좌측메뉴에서 Build -> Authentication 순으로 선택

Get started 선택

Email/Password 선택

Enable 버튼 켜고 저장

생성완료

유저추가하려면 메뉴에서 Users 선택 후 Add user 선택

이메일, 비밀번호 입력 후 저장

생성된 유저 확인

애플리케이션에서 서비스 활용하기

애플리케이션과 파이어베이스 연결

 

파이어베이스 - 연결하기 (앵귤러, 리액트)

파이어베이스는 데이터 저장에 필요한 데이터베이스, 인증 및 호스팅 등 다양한 서버 측 기능을 제공하는 구글의 통합 서비스입니다. 이미 구축된 서버에 프론트 애플리케이션을 연동하고 파이

jin-co.tistory.com

앵귤러

파이어베이스를 애플리케이션과 연동한 뒤 아래와 같이 auth모듈을 추가

// app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './components/auth/login/login.component';
import { AngularFireModule } from '@angular/fire/compat';
import { environment } from '../environments/environment';
import { AngularFireAuthModule } from '@angular/fire/compat/auth';

@NgModule({
  declarations: [
    AppComponent,
    LoginComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    FormsModule,
    HttpClientModule,
    AngularFireModule.initializeApp(environment.firebase),
    AngularFireAuthModule, // Auth module
  ],
  providers: [
    
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

여러 컴포넌트에서 공유가능하도록 서비스를 만들고 아래와 같이 코드를 작성

▶ 로그인 / 로그아웃

.signInWithEmailAndPassword(email, password)
.signOut()
// auth.service.ts

import { Injectable } from '@angular/core';
import { Auth, createUserWithEmailAndPassword } from '@angular/fire/auth';
import { AngularFireAuth } from '@angular/fire/compat/auth';

@Injectable({ providedIn: 'root' })
export class AuthService {
  constructor(private afa: AngularFireAuth) {}

  login(email: string, password: string) {
    this.afa.signInWithEmailAndPassword(email, password);
  }
  
  logout() {
    this.afa.signOut();
  }
}

템플릿에서 이메일과 비밀번호를 입력할 수 있는 로그인 폼을 만들고 

<!-- login.component.html -->

<form #form="ngForm" (submit)="onSubmit(form)">
  <mat-form-field>
    <input
      placeholder="email"
      matInput
      type="email"
      required
      name="email"
      #email="ngModel"
      ngModel
    />
  </mat-form-field>
  <mat-form-field>
    <input
      placeholder="password"
      matInput
      type="password"
      required
      name="password"
      #password="ngModel"
      ngModel
    />
  </mat-form-field>
  <button mat-raised-button>Login</button>
  <small>Not registered yet? <a routerLink="/signup">Register</a></small>
</form>

해당 클래스 파일에서 템플릿과 서비스의 로그인 기능을 연결하면 완성

// login.component.ts

import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Router } from '@angular/router';
import { AuthService } from 'src/app/services/auth';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.css', '../auth.style.css'],
})
export class LoginComponent implements OnInit {
  constructor(private authService: AuthService, private router: Router) {}

  ngOnInit(): void {}

  onSubmit(form: NgForm) {
    if (form.valid) {
      try {
        this.authService.login(form.value.email, form.value.password);
        this.router.navigate(['/'])
      } catch (error) {
        console.log(error);
      }
    }
    form.resetForm();
  }
}

리액트

▶ 가입

회원가입 컴포넌트에 가입에 필요한 서비스들 가져오기

import {
  getAuth,
  createUserWithEmailAndPassword  
} from 'firebase/auth'

인증 초기화

const auth = getAuth()

createUserWithEmailAndPassword 함수에 초기화한 인증, 이메일, 비밀번호를 전달합니다. 해당 함수는 실행 후 등록결과를 반환합니다.

const newUser = await createUserWithEmailAndPassword(
  auth,
  email,
  password
)

실행결과 이상이 없다면 파이어베이스에도 등록됩니다.

사용자가 등록되면 초기화한 인증객체에 해당 유저가 추가됩니다. 이를 활용하여 표시되는 이름 등 추가정보를 더하거나 수정할 수 있습니다.

사용자정보 수정에 필요한 기능을 가져와서

import { updateProfile } from 'firebase/auth'

해당 함수를 통해 정보 수정

updateProfile(auth.currentUser, {
  displayName: 'name'
})


회원등록이 되면 파이어베이스에 유저로 등록되지만 해당 데이터를 데이터베이스에 저장된 테이블에서 참고하는 것이 어렵기 때문에 데이터베이스에서 유저를 참고할 필요가 있는 경우 유저 테이블을 만드는 것이 유리합니다.

 

예를 들어, 파이어스토어를 활용한다면 아래처럼 파이어베이스 구성 파일, 다큐먼트 등 필요한 기능들을 가져오고

import { db } from '../firebase.config'
import { doc, setDoc } from 'firebase/firestore'

데이터베이스 다큐먼트에 저장

await setDoc(doc(db, '<collectionName>', <user>.uid), <newUser>)

 유저 데이터를 데이터베이스에 생성할 때 민감한 정보는 미리 삭제합니다.

잘못된 예
올바른 예

▶ 로그인

로그인 컴포넌트에 로그인에 필요한 서비스들을 가져오기

import { getAuth, signInWithEmailAndPassword } from 'firebase/auth'

인증을 초기화

const auth = getAuth()

signInWithEmailAndPassword 함수에 초기화한 인증, 이메일, 비밀번호를 전달, 해당 함수는 작업결과를 반환합니다.

await signInWithEmailAndPassword(auth, email, password)


※ 새로고침 등으로 로그인한 사용자 정보가 브라우저에서 사라지는 것을 방지하기 위해 파이어베이스는 인덱스드 디비에 로그인한 사용자 정보를 저장함.


▶ 현재 사용자 표시하기

위에서 언급한 대로 인증 서비스는 현재 사용자의 정보를 담고 있기 때문에 이를 활용하면 로그인된 사용자 정보활용이 가능합니다.

import { getAuth } from 'firebase/auth'
const auth = getAuth()


★ 화면을 새로고침 하면 컴포넌트가 표시되는 시점이 유저의 정보를 가져오는 시점보다 빨라지기 때문에 아래와 같이 컴포넌트에서 유저를 인식할 수 없게 됩니다.

이를 방지하려면 컴포넌트가 활성화되는 시점을 조금 늦춰주어야 하는데, 이를 위해 onAuthStateChanged를 사용해 보겠습니다.

 

먼저, 해당 함수와 인증을 가져오고

import { getAuth, onAuthStateChanged } from 'firebase/auth'

인증 초기화

const auth = getAuth()

유즈이펙트 훅에 함수를 아래와 같이 구현

useEffect(() => {
  onAuthStateChanged(auth, (user) => {
    if (user) {
      setUserReady(true)
    }
  })
}, [])

완성되면 새로고침을 하더라도 에러가 발생하지 않습니다.


▶ 비밀번호 교체

로그아웃을 사용할 컴포넌트에 인증객체 및 비밀번호 교체 함수 가져오기

import { getAuth, sendPasswordResetEmail } from 'firebase/auth'

인증 초기화

const auth = getAuth()

비밀번호 교체 함수를 호출

await sendPasswordResetEmail(auth, email)

▶ 로그아웃

로그아웃을 사용할 컴포넌트에 인증객체를 가져오기

import { getAuth } from 'firebase/auth'

초기화 후

const auth = getAuth()

사인아웃 함수를 호출

auth.signOut()


이상으로 파이어베이스 이메일, 비밀번호 인증 서비스를 여러 애플리케이션에서 사용하는 방법을 알아보았습니다.


참고

https://firebase.google.com/docs/auth/web/start

 

웹사이트에서 Firebase 인증 시작하기

Google I/O 2023에서 Firebase의 주요 소식을 확인하세요. 자세히 알아보기 의견 보내기 웹사이트에서 Firebase 인증 시작하기 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분

firebase.google.com

 

 

 

728x90
반응형