카테고리 없음

Firebase - Project 생성 및 Application 적용, Authentication 회원가입/로그인 (깃허브)

유혁스쿨 2024. 2. 20. 12:33
728x90
반응형

Firebase Project 생성 및 Application 적용부터 Authentication 로그인 과정

 

Firebase Project 생성 및 Application 적용

 

 

 

 

 

 

 

 

 

 

 

NPM을 사용할지 CDN방식을 사용할지 정한다.

필자는 터미널에서 NPM 명령어를 통해 설치했다.

> npm install firebase @10.1.0

 

 

2. SDK 모듈 파일 추가

[ firebase.ts ] 혹은 js ()

import { initializeApp } from "firebase/app";

const firebaseConfig = {
  apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  authDomain: "sample-example-aee43.firebaseapp.com",
  projectId: "sample-example-aee43",
  storageBucket: "sample-example-aee43.appspot.com",
  messagingSenderId: "xxxxxxxxxxxx",
  appId: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

};

const app = initializeApp(firebaseConfig);

코드 예시이기 때문에 복사해도 실행 안됨. 본인 코드를 사용해야함.

 

 


Firebase Authentication 세팅 및 기본 로그인

 

 

콘솔화면 중앙의 Authentication 카드상자를 선택한다.

다음 페이지에서 뜨는 시작하기 버튼을 눌러 활성화 한다. (이미지 생략됨)

 

 

로그인 방법 탭에서 기본제공업체 - 이메일/비밀번호 방식을 선택한다.

 

 

사용설정(Enable) 토글을 On으로 설정후 저장

 

 

 

Application에서 적용한다.

기존 Firebase Configuration을 정의한 모듈 파일에서 설정한다.

import { getAuth } from "firebase/auth"; // 코드 추가!
const auth = getAuth(app); // 코드 추가! firebase/auth를 import해야함

위 코드를 추가한다.

 

 

[ firebase.ts ] 혹은 js

import { initializeApp } from "firebase/app";
import { getAuth } from "firebase/auth"; // 코드 추가!

const firebaseConfig = {
	/* 생략 */
};

const app = initializeApp(firebaseConfig);
const auth = getAuth(app); // 코드 추가! firebase/auth를 import해야함

 

 

어플리케이션 전역에 인증객체를 공급한다.

[ App.tsx ] 혹은 js

export default function App() {
    /**
     * auth - 인증객체
     * currentUser, signOut, updateCurrentUser 등
     * 로그인한 사용자, 로그아웃, 사용자정보수정 등 인증관련 정보,기능 제공
     * authStateReady() - 인증 상태 준비여부 대기
     * Firebase가 쿠키와 토큰을 읽고 백엔드와 통신하여 로그인여부를 확인하는동안 기다린다.
     * Promise<void> 객체를 반환한다.
     */
    await auth.authStateReady() //인증상태 준비여부 대기 

}

일반 회원가입

 

[ 계정 생성 및 닉네임 설정 ]

import { createUserWithEmailAndPassword, updateProfile } from "firebase/auth"
import { auth } from "./firebase"

/** 
 * [ 계정 생성 ]
 * createUserWithEmailAndPassword(arg1, arg2, arg3)
 * 전달받은 받은 인증객체, 이메일, 패스워드를 통해 FireBase에서 인증처리
 * 인증성공시 자격증명을 반환한다.
 */
const credentials = await createUserWithEmailAndPassword(auth, /*이메일*/, /*패스워드*/)

 * 
/** 
 * [ 닉네임 설정 ]
 * updateProfile(arg1, arg2)
 * 사용자 정보, 닉네임 객체 를 매개변수로 전달한다.
 * 계정 생성 후 반환받은 자격증명 객체로부터 사용자 정보를 가져올 수 있다.
 * 닉네임 객체 형태 : {displayName: /* 설정할 닉네임 */}
 */
await updateProfile(credentials.user, {displayName: userInfo.name,})

console.log(credentials.user) //가입 된 사용자 정보 조회

로그인에 성공한 사용자 정보는 auth객체의 currentUser 속성을 통해 조회가 가능하다.

 

 

 

[ CreateAccount.tsx ] 회원가입 폼 샘플

import { createUserWithEmailAndPassword, updateProfile } from "firebase/auth"
import { useState } from "react"
import { auth } from "./firebase"
import { Link, useNavigate } from "react-router-dom"
import { FirebaseError } from "firebase/app"
import GithubButton from "../components/github-btn"

export default function CreateAccount() {
  const navigate = useNavigate();
  const [isLoading, setLoading] = useState(false);
  const [error, setError] = useState("")
  const [userInfo, setUserInfo] = useState({name: '', email: '', password: ''})

  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const {target: {name, value}} = e;
    // setUserInfo({...userInfo, [name]: value})
    setUserInfo(currentUserInfo => ({...currentUserInfo, [name]: value})) // 콜백 상태업데이트
  }

  const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    setError("")
    if(isLoading || userInfo.name === "" || userInfo.email === "" || userInfo.password === "") return;
    console.log(userInfo.name, userInfo.email, userInfo.password)
    try {
      setLoading(true)
      // 계정 생성
      const credentials = await createUserWithEmailAndPassword(auth, userInfo.email, userInfo.password) //인증객체, 이메일, 패스워드 FireBase에 전달 -> 인증성공시 자격증명 반환
      // 사용자 프로필이름 지정
      await updateProfile(credentials.user, {displayName: userInfo.name,})
      // 회원가입 성공시 홈페이지 리다이렉트
      navigate("/")
    } catch (e) {
      // setError
      if(e instanceof FirebaseError) { // 회원가입 실패시
        setError(e.message)
      }
    } finally { // navigate에 의해 리다이렉트 되었더라도 무조건 실행된다.
      setLoading(false)
    }
  }

  return (
  <>
    <form onSubmit={onSubmit}>
      <input onChange={onChange} name="name" value={name} placeholder="Name" type="text" required/>
      <input onChange={onChange} name="email" value={email} placeholder="Email" type="email" required/>
      <input onChange={onChange} name="password" value={password} placeholder="Password" type="password" required/>
      <input type="submit" value={isLoading ? "Loading...." : "Create Account"}/>
    </form>
    {error !== "" ? <Error>{error}</Error>: null}
  </>
  )
}

 

 

일반 로그인

import { signInWithEmailAndPassword } from "firebase/auth"
import { auth } from "./firebase"

/** 
 * [ 로그인 ]
 * signInWithEmailAndPassword(arg1, arg2, arg3)
 * 전달받은 받은 인증객체, 이메일, 패스워드를 통해 FireBase에서 로그인 인증처리
 * 로그인 인증 성공시 자격증명을 반환한다.
 * 회원가입이 아닌 로그인 이므로 
 * 자격증명이 아닌 어플리케이션 전역에 ReadyState 했던 authentication객체로부터
 * 로그인이 된 사용자 정보를 조회한다.
 */
const credential = await signInWithEmailAndPassword(auth, /*이메일*/, /*패스워드*/)
console.log(auth.currentUser) // 로그인 된 사용자 정보 조회

 

[ Login.tsx ] 로그인 폼 샘플

import { signInWithEmailAndPassword } from "firebase/auth"
import { useState } from "react"
import { auth } from "./firebase"
import { Link, useNavigate } from "react-router-dom"
import { FirebaseError } from "firebase/app"

export default function Login() {
  const navigate = useNavigate();
  const [isLoading, setLoading] = useState(false);
  const [userInfo, setUserInfo] = useState({email: '', password: ''})
  const [error, setError] = useState("")

  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const {target: {name, value}} = e;
    setUserInfo(currentUserInfo => ({...currentUserInfo, [name]: value})) // 콜백 상태업데이트

  }

  const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    setError("")
    if(isLoading || userInfo.email === "" || userInfo.password === "") return;
    try {
      setLoading(true)
      // 로그인
      await signInWithEmailAndPassword(auth, userInfo.email, userInfo.password)
      console.log(auth.currentUser) // 로그인 된 사용자 정보 조회
      // 로그인 성공시 홈페이지 리다이렉트
      navigate("/")
    } catch (e) {
      if(e instanceof FirebaseError) { // 로그인 실패시
        console.log(e.code, e.message)
        setError(e.message)
      }
    } finally { // navigate에 의해 리다이렉트 되었더라도 무조건 실행된다.
      setLoading(false)
    }
  }

  return (
  <>
    <form onSubmit={onSubmit}>
      <input onChange={onChange} name="email" value={email} placeholder="Email" type="email" required/>
      <input onChange={onChange} name="password" value={password} placeholder="Password" type="password" required/>
      <input onChange={onChange} type="submit" value={isLoading ? "Loading...." : "Log in"}/>
    </form>
    {error !== "" ? {error}: null}

  </>
  )
}

 

갓허브 Auth Social 로그인

 

Firebase 콘솔의 Authentication에서 새 제공업체 추가를 선택한다.

 

깃 으로부터 인증키를 받아 저장해야한다.

 

깃허브 로그인 후 Profile사진을 누르면 열리는 우측 네비게이션에서 Settings선택.

좌측 네비게이션 최 하단의 Developer settings 선택.

좌측 네비게이션 중간 OAuth Apps선택.

[New OAuth App] 버튼 클릭

 

 

Application name, Homepage URL, Authentication callback URL 을 입력한다.

 

Homepage URL을 따로 검사하지는 않으므로 아직 웹사이트가 없으면 Firebase의 로그인 제공업체 단계에서 제공하는 최 하단의 승인 콜백 URL 링크를 넣어준다. (도메인 까지만 넣자!)
Authentication callback URL에는 풀 Link를 모두 입력해줘야한다.

 

 

Client ID와 Client secrets  키를 각각 제공받는다.

이때, 한번 제공받은 Client secrets는 다시 제공받을 수 없다.

(타인에게 노출되면 절대 안됨.)

 

 

모자이크 된 부분을 각각 Firebase 제공업체 구성 2/2단계에 입력 후 저장한다.

 

 

정상적으로 새로운 제공업체가 추가되었다.

 

import { GithubAuthProvider, signInWithPopup, signInWithRedirect } from "firebase/auth"
import { auth } from "../routes/firebase"

/**
 * firebase 인증객체와, 깃허브 인증 제공객체를 함께 전달해야한다.
 */
const provider = new GithubAuthProvider()
const gitPopCredential = await signInWithPopup(auth, provider); // 팝업
const gitRedCredential = await signInWithRedirect(auth, provider); // 페이지로이동
console.log(auth.currentUser)

이때, firebase/auth/cordova가 아닌 firebase/auth경로로 import해야한다.

두가지 방식중 하나를 선택하면 된다. (팝업으로 할지, 페이지를 이동할지)

 

import { GithubAuthProvider, signInWithPopup } from "firebase/auth"
import { auth } from "../routes/firebase"
import { useState } from "react"
import { useNavigate } from "react-router-dom"

import { FirebaseError } from "firebase/app"

export default function GithubButton() {
  const navigate = useNavigate();
  const [error, setError] = useState("")

  const onClick = async(e: React.React.ReactHTMLElement<HTMLButtonElement>) => {
  	e.preventDefault();
    try {
      setError("")
      const provider = new GithubAuthProvider()
      await signInWithPopup(auth, provider); // 팝업
      // await signInWithRedirect(auth, provider); // 페이지로이동
      navigate("/")
    } catch (e) {
      if(e instanceof FirebaseError) { // 로그인 실패시
        console.log(e.code, e.message)
        setError(e.message)
      }
    }
  }

  return (
    <>
    <button onClick={onClick}>
      Contiune with Github
    </button>
    {error !== "" ? error: null}
    </>
    )
}

 

 

 

728x90
반응형