[React] 로그인, 회원가입, 로그아웃 기능 구현

Kyoo·2022년 5월 2일
2

해당 글은 프론트엔드를 공부하면서 기록 목적으로 작성한 내용입니다.
잘못된 내용이 있다면 제보 부탁드립니다. 🙇‍♂️


오늘은 미니 프로젝트를 진행하면서 Firebase를 이용한 로그인, 회원가입, 로그아웃 기능을 구현한 내용에 대해 기록을 남기고자 한다.

1. 라이브러리 설치

  • firebase
  • redux, react-redux
  • redux-thunk
  • redux-devtools-extension
  • history
  • connected-react-router

2. 프로젝트 구조

.src
├── App.css
├── App.js
├── components
│   ├── Footer.js
│   ├── Header.js
│   └── index.js
├── elements
│   ├── Button.js
│   ├── Grid.js
│   ├── Input.js
│   ├── Text.js
│   └── index.js
├── index.css
├── index.js
├── pages
│   ├── Home.js
│   ├── Login.js
│   ├── Post.js
│   ├── SignUp.js
│   └── index.js
├── redux
│   ├── actions
│   │   └── authAction.js
│   ├── configureStore.js
│   └── reducers
│       ├── authReducer.js
│       └── index.js
├── result.md
└── shared
    ├── Cookie.js
    ├── Permit.js
    └── firebase.js

3. 초기 세팅

3-1. Firebase 연동

  • src/shared/firebase.js

    import firebase from "firebase/app";
    import "firebase/auth";
    
    const firebaseConfig = {
      apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
      authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
      projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
      storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
      messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
      appId: process.env.REACT_APP_FIREBASE_APP_ID,
    };
    
    firebase.initializeApp(firebaseConfig);
    
    export const apiKey = firebaseConfig.apiKey;
    export const authService = firebase.auth();
    

3-2. 리덕스 세팅

  • src/redux/configureStore.js

    import { createStore, applyMiddleware } from "redux";
    import { composeWithDevTools } from "redux-devtools-extension";
    import thunk from "redux-thunk";
    import rootReducer from "./reducers";
    import { history } from "./reducers";
    
    let store = createStore(
      rootReducer,
      composeWithDevTools(
        applyMiddleware(thunk.withExtraArgument({ history: history }))
      )
    );
    
    export default store;
  • src/redux/reducers/index.js

    import { combineReducers } from "redux";
    import authReducer from "./authReducer";
    import { createBrowserHistory } from "history";
    import {connectRouter} from "connected-react-router";
    
    export const history = createBrowserHistory();
    
    export default combineReducers({
      auth: authReducer,
      router: connectRouter(history),
    });

상세 코드 확인하기
https://github.com/Kyoo130/fitgoing/tree/main/src/redux


4. 기능 구현

4-1. 회원 가입

  • firebase.js에 만들어둔 authService 가져오기
  • 리덕스에서 signUpFB 회원가입 함수 만들기
  • authService.createUserWithEmailAndPassword()로 회원가입 시키기
  • SignUp.js 컴포넌트에서 signUpFB를 호출하기
  • 가입이 완료된 후, display_name 업데이트하기
  • 리덕스의 user 정보 업데이트 후 메인 페이지'/'로 이동하기

4-2. 로그인

  • firebase.js에 만들어둔 authService 가져오기
  • 리덕스에서 loginFB 로그인 함수 만들기
  • authService.signInWithEmailAndPassword()로 로그인 시키기
  • Login.js 컴포넌트에서 loginFB를 호출하기
  • 리덕스의 user 정보 업데이트 후 메인 페이지'/'로 이동하기

4-3. 로그아웃

  • firebase.js에 만들어둔 auth 가져오기
  • 리덕스에서 logOutFB 로그인 함수 만들기
  • authService.signOut()로 로그아웃 시키기
  • Header.js 컴포넌트에서 logOutFB를 호출하기
  • 리덕스의 is_login 정보 업데이트 후 메인 페이지'/'로 이동하기

5. 문제 해결

5-1. 로그인 유지 불가 현상

위 방법을 통해 회원가입, 로그인, 로그아웃 기능을 구현하였지만,
로그인 후 새로고침 시 로그인 정보가 유지가 안되는 문제가 발생하였다.

이 문제를 해결하기 위해 Firebase 공식 문서를 찾아보니,
localsession을 이용하여 인증 상태를 유지하는 방법을 찾았다.

하지만, local의 경우 브라이저를 닫아도 인증 상태가 유지되고, 사용자가
직접 로그아웃 버튼을 눌러 인증 정보를 삭제해야하기 때문에 적합하지 않았고,

session의 경우 현재의 세션이나 탭에서만 상태가 유지되며, 사용자가 직접
로그아웃을 하거나, 브라우저를 닫으면 인증 정보가 삭제되므로 이를 선택하였다.

Firebase 공식 문서 참고
https://firebase.google.com/docs/auth/web/auth-state-persistence?hl=ko&authuser=0

5-2. 로그인 기능 수정 (session 인증 추가)

  • firebase.js에 만들어둔 authService 가져오기
  • 리덕스에서 loginFB 로그인 함수 만들기
  • authService.setPersistence(firebase.auth.Auth.Persistence.SESSION)로 세션 정보 생성
  • authService.signInWithEmailAndPassword()로 로그인 시키기
  • Login.js 컴포넌트에서 loginFB를 호출하기
  • 리덕스의 user 정보 업데이트 후 메인 페이지'/'로 이동하기

5-3. 로그인 정보 체크

  • 리덕스에서 logInCheckFB 로그인 체크 함수 만들기
    • user 정보가 있을 경우 onAuthStateChanged()로 사용자 정보 업데이트
    • user 정보가 없을 경우 로그아웃 함수 호출
  • 새로고침 발생 시 useEffect를 활용하여 session 체크 후 logInCheckFB 호출
  • session 정보가 있을 경우 Header.js 로그아웃 버튼만 노출 시키기

상세 코드 확인하기
https://github.com/Kyoo130/fitgoing/blob/main/src/redux/actions/authAction.js


6. 마무리

회원가입, 로그인, 로그아웃 기능을 기존에도 구현해 봤지만, 새로운 프로젝트를 시작할 때마다 새롭게 느껴지고, 특히 이번에는 로그인 유지 뿐만 아니라, 처음 session 대신 cookie를 사용하였는데, history가 정상적으로 작동되지 않아 여러번 코드를 뜯어고치면서 문제를 해결하였다.

역시, 끝까지 문제를 물고 늘어지니 시간이 걸릴 뿐, 안되는 일은 없는 것 같다!
아직 미니 프로젝트가 끝난 게 아니니 다음 난관에 부딪혀 보자!

profile
프론트엔드 개발자가 되기 위해 전진하고 있습니다~

0개의 댓글

관련 채용 정보