[클론 코딩-트위터(React, Firebase)] 회원가입, 로그인, 소셜 로그인 기능 만들기 (누이터와 파이어베이스 연동, authentication)

안지수·2023년 4월 29일
0
post-custom-banner

😀 파이어베이스 로그인 준비하기

: 파이어베이스 인증기능 연동 (로그인 과정)

1. useState 함수 위치 이동하기

: useState(상태) app.js로 옮기기 (상태 App 컴포넌트에서 관리)
-> AppRouter: 라우터 역할, 코드의 가독성

-> 밑줄 친 부분은 현재 연도를 반환해주는 자바스크립트 함수 (footer 엘리먼트에 올해 연도 출력)
-> jsx에서 함수를 사용하려면 중괄호
-> ©: jsx에서 copyright 기호 출력

-> app.js와 Router.js를 위와 같이 수정해준다.


-> index.js에서 app.js를 불러온다. 그 후 AppRouter을 isLoggedIn의 상태와 함께 컴포넌트를 렌더링한다. 그랬더니, false이므로 Auth 컴포넌트가 실행되고, footer에 의해서 현재 연도와 글자가 출력된다.

2. jsconfig.json 파일과 함께 절대 경로 적용하기


-> import 문 사용 시, 위는 상대 경로를 사용!
-> 가독성 떨어짐
-> 절대 경로로 바꿔보자

  • jsconfig.json: 리액트에서 사용할 자바스크립트를 위한 설정 파일
    -> 자바스크립트 설정을 우리 입맛에 맞게 바꿀 수 있음!
    -> 이 파일을 통해 절대 경로 설정 가능

    -> 루트 폴더(nwitter)에 'jsconfig.json' 이름으로 위와 같이 코드 작성하자
    -> src폴더를 기준으로 파일 경로 적을 수 있어서 가독성↑

3. 컴포넌트의 import문 수정하기

: 상대 경로로 설정된 곳 절대 경로로 바꾸기
-> import 문 수정 후에는, 서버 다시 시작해야 화면 제대로 출력!! (ctrl+c -> npm run start)
-> 코드의 import 부분들을 아래와 같이 수정해준다.

  • app.js
  • Router.js
  • index.js

    -> firebase 확인이 끝났으니, 위 두 줄을 지워준다!

4. firebase.js의 파일 이름 바꾸기

  • 절대 경로의 단점: 파일 이름과 npm install로 설치한 패키지 이름이 같으면 오류 발생

    -> firebase라는 이름의 패키지를 설치하려나보다

5. 파이어베이스 인증 모듈 사용하기

  • 파이어베이스 특징:
    특정 모듈 사용 시, 모듈 추가로 불러와야 함
    -> 인증 모듈 사용하기 위해서: firebase/auth를 추가로 import해줘야 함

  • fbase 코드 수정

    -> 4, 15, 16 줄을 위와 같이 수정해줘
    -> 인증 모듈을 위해 4번째 줄처럼 firebase/auth 불러와야 함
    -> 'firebase.initializeApp(firebaseConfig)'는 다른 파일에서 참조할 필요 없으므로 그 파일 안에서만 실행하도록
    -> 로그인 위해서 firebase.auth()는 다른 파일에서 참조할 것이므로 authService에 담아 내보내도록
    -> 다른 파이어베이스 관련 모듈을 더 내보낼 수도 있으므로 named export!! (여러 모듈 내보내도록)

  • authServie 사용하기 (isLoggedIn이 있는 곳에)

    -> app.js의 4, 8번 코드를 수정해줘 (authService를 잘 받아오는지 확인하기 위해서)
    -> 상위 컴포넌트로부터 받은 프롭스는 구조분해로 받음!
    -> authServiec로 내보낸 auth 모듈에는 현재 로그인 사람 확인하는 'currentUser' 함수 포함
    -> 로그인 하지 않은 상태라면 null 반환

    -> 그런데, 실행했을 때 위와 같이 오류가 나타났다.
    ✔️ 오류 해결:


-> 이번엔, 위와 같이 수정하여 currentUser에 따라 isLoggedIn 상태를 바꿔줄 수 있다.

import{authService}와 같이 모듈 단위로 import 하는 이유:
-> firebase와 같은 패키지에는 수많은 기능(모듈)들이 들어있어서, 파일 크기가 매우 크다. 따라서, 모두를 import 하면 프로그램이 무거워지므로, 필요한 모듈들만 import하여 사용한다. (여기서는 인증 기능을 사용하기 위해 firebase 패키지 중에서도 auth()모듈을 호출하였다.)
React.StrictMode란? (index.js 파일)
-> console.log 함수가 2번 실행된다. 오류를 더 쉽게 포착

-----> 여기까지는 파이어베이스 인증 기능을 사용하기 위해, 파이어베이스와 연동하고 모듈을 불러오는 작업을 하였다.

😀 파이어베이스 로그인 설정하기

: 이메일/비번 기반 로그인, 구글, 깃허브 소셜 로그인 누이터에 적용하기
-> 파이어베이스 콘솔에 접속해서 파이어베이스 기본 설정

1. 파이어베이스 인증 설정하기

  • 파이어베이스 콘솔: console.firebase.google.com에 접속하여, nwitter 프로젝트를 선택
  • authentication -> 시작하기 -> user탭 -> 로그인 방법 설정

2. 이메일, 비밀번호 로그인 설정하기


-> 이메일/비밀번호에서 위와 같이 설정해준다.

3. 구글 소셜 로그인 설정하기


-> 구글 로그인도 위와 같이 설정해준다. 공개용 이름은 그대로 두고, 지원 이메일에는 기본값 설정해준다.

4. 깃허브 소셜 로그인 설정하기


-> 아이디, 비번 입력후, 링크를 복사한 후 저장을 누른다.

-> 깃허브에 접속하여 로그인 관련 설정을 해줄 것이다.

-> developer settings에 들어가준다.

-> oAuth apps -> register a new application
(oAuth: 다른 사이트의 계정 정보의 접근 권한만 받아 해당 계정을 이용해 로그인할 수 있게 해주는 기능, 사용자에게 별도의 아이디와 비번을 요구하지 않음)

-> homepage URL은 아까 firebase 홈페이지에서 승인된 도메인에서 'firebase.com으로 끝나는 주소 앞에 http://를 붙여서 적어준다.
-> 그 아래 URL은 아까 복사한 주소를 넣어준다.
-> client id를 복사해서 아까 그 페이지로 돌아가 클라이언트 id에 넣어준다.

-> 여기서 비밀번호를 생성해 아까 그 페이지로 돌아가 클라이언트 보안 비밀번호에 적어준다.

---> 여기까지는 파이어베이스 로그인 설정을 해주었다. 로그인할 서버가 준비된 것이다.

5. 로그인 폼 기본 구조 만들기

: Auth.js에 로그인을 위한 폼 생성

-> 위와 같이 Auth.js 파일을 수정해준다.

-> 그러면 위와 같이 폼이 나타난다.
-> 구글, 깃허브 소셜 로그인은 파이어베이스 서버에 로그인 요청만 하면됨! (아까 그 사이트들에 대한 접근 권한을 허용받았음)

6. 로그인 폼이 상태를 업데이트하도록 만들기

폼이 실행되게 하려면?
: useState 함수로 상태 만들어주고, onChange, onSubmit 함수로 이벤트 연결해줘야 함

-> Auth 파일을 위와 같이 수정해준다.

-> 폼에 입력을 시도해보면, input element의 name 속성에 지정한 값이 출력됨을 알 수 있다. event.target.name을 통해 어떤 엘리먼트에 입력을 시도하고 있는지 구분할 수 있음

-> 상태를 업데이트하도록 위와 같이 코드를 다시 수정
-> event.target에서 name, value 값을 가져와서 name에 따라 이메일과 비밀번호 정보를 업데이트하도록 하였다.

폼 요소를 위한 3가지 이벤트

  • onSubmit: 폼 제출 시 발생/ 이벤트 발생 시 페이지 새로고침
  • onChange: 폼의 입력 요소에 변경 생길 시
  • onInput: 요소의 값 변경될 시

    -> onChange={onChange}의 의미: 입력 요소에 변경이 생기면, onChange함수를 호출. 그러면 그 함수로 이동해서 event.target의 name을 콘솔에 출력해준다.
    -> onSubmit을 했을 경우에는 event.preventDefault()를 실행해주는데, 이는 리액트의 초기화를 방지

---> 여기까지는 로그인을 위한 설정들을 해주었다. firebase와 연동하고, 폼을 만들고, 입력 발생 시, '이메일과 비번을 업데이트' 해주는 것까지 하였음.

😀 이메일, 비밀번호 인증 기능 사용해 보기

: 회원가입 기능과 인증 기능
-> 파이어베이스에서 제공하는 기능

1. onSubmit 함수에서 로그인과 회원가입 분기시키기




-> 위와 같이 코드를 수정
-> newAccount로 상태를 관리하여, 그 값에 따라 회원가입/로그인을 할 수 있도록 분기

2. 파이어베이스로 로그인과 회원가입 처리하기

: 파이어베이스 적용
-> EmailAuth Provider에 속한 CreateUserWithEmailAndPassword(인자로 전달받은 이메일, 비번을 파이어베이스 DB에 저장) 함수와 signInWithEmailAndPassword(인자로 받은 이메일, 비번을 데이터베이스에 전달하여 확인 후 로그인) 함수 사용

-> authService에 그 함수들 포함

-> 위와 같이 Auth.js 파일을 수정
-> async, await: 서버로 값을 요청해서 결괏값을 수신 받기까지 시간 소요/ 인증 처리 이후 누이터 실행되어야 하므로 기다렸다 실행하라
-> try, catch: 로그인 또는 회원가입의 성공과 실패 처리

  • async, await: 비동기를 동기처럼 보이게
    -> try, catch로 에러 핸들링 가능
    -> 위의 코드에서는, 알아서 순서대로 처리하지만, 인증 처리 이후 누이터 실행하도록 명시 중

  • 로그인을 지속시켜주는 setPersistence
    : 3가지로 나누어 로그인 상태 관리

  1. local: 웹 브라우저 종료해도 로그인 유지
  2. session: 웹 브라우저의 탭 종료 시 로그아웃
  3. none: 새로고침하면 로그아웃
    --> 우리는 local 옵션 사용할 것! default 값이라서 따로 설정해주지 않아도 됨

---> 여기까지는 회원가입/로그인 시의 데이터 처리 (auth모듈의 함수들 이용해서), 회원가입 기능까지 완료!

3. 사용자 정보가 저장되어 있는 곳 살펴보기

: local 옵션으로 저장한 로그인 정보는 어디에 저장?
-> 브라우저 내의 Indexed DB에 저장

-> 개발자 도구의 application-> indexed db에서 사진 속의 경로에 내가 회원가입 시 입력한 이메일이 들어있음을 알 수 있다.
-> indexed db에 저장하기 위한, 코드를 따로 적어주지 않았지만, 파이어베이스에 의한 자동으로 잘 저장!

---> 즉, 여기까지는 파이어베이스(인증 기능 함수들 사용)를 이용해 회원가입에 성공했고, 로그인을 유지시킬 수 있는데 그 정보들은 indexed db에 저장된다는 것!

😀 로그인, 로그아웃하기

: 앞서 배운 회원가입과 즉시 로그인, 정보 저장 기능을 누이터에 적용

로그인 처리 후 currentUser가 null인 이유 알아보기

: 비동기 처리이기 때문! (신호 보냄-> 받음-> 처리 순서대로!) but, 처리 과정 생략
-> 로그인 처리 이후, 누이터에서 신호받기까지 시간 간격 (신호 받은 이후 화면에 출력해줘야 함. 비동기이므로)
-> 요청은 보냈지만, 데이터를 기다리고 있지 않음
-> 리액트 생명주기를 통해 해결

1. 딜레이 눈으로 확인해보기

: setInterval(밀리초 단위) 함수 (신호 받기까지의 걸리는 시간 확인)
-> 2번째 인자의 시간 간격마다 1번째 인자의 코드 실행
-> authService.current를 2초마다 실행하여 로그인 처리 완료까지의 시간 계산

  • App.js 파일

    -> 2초마다 null이 아닌 로그인 객체가 console에 출력됨
    -> 파이어베이스의 값을 기다리지 않은 채로, currentUser를 참조한 것이 문제였음
    -> currentUser의 변경 시점을 어떻게 잡아낼까?
    -> currentUser가 변경되는 시점을 알아야 함!
    -> useEffect 함수 사용

2. useEffect 함수 사용하기

❤️ 이부분 어려우니 복습하기!!!

: 특정 시점에 실행되는 함수
-> 파이어베이스 로그인 정보를 받게 되었을 때
-> currentUser가 변경되는 시점을 알기위해(console에 null이 아닌 객체를 제대로 출력하기 위해-항상 로그인 되어있지 않은 것으로 표시되는 것을 해결)
-> useEffect로 로그인 정보 받게된 시점 잡아낸 후, 보여줄 화면 렌더링
-> 파이어베이스의 onAuthStateChange함수 이용
---> 인증 상태 감지: onAuthStateChange, useEffect

-> 밑줄친 부분과 useEffect를 수정
-> 2번째 인자를 []로 지정해야 컴포넌트가 최초로 렌더링이 완료되었을 때, 1회만 동작
-> useEffect 함수에 의해, 컴포넌트 렌더링 이후 인증 상태 출력

-> 초반엔 로그인이 안되어있으므로 false이고, 회원가입 시, 자동으로 로그인되어, 그 후로 인증 상태가 감지되는 경우에만, 그 값이 전달되어 참이므로 home 컴포넌트가 실행된다. 그렇지 않으면, false가 되어 Auth 컴포넌트 실행!

---> 여기까지는, 회원가입하면 자동로그인 되고, 정보 저장되고, 로그인 후, 로그인 처리 결과 업데이트되도록

3. 로그아웃 어떻게?

: indexed DB를 clear (수동)
-> 다시 회원가입 창으로 돌아옴
-> 로그아웃은 소셜 로그인 배운 이후에 다시!

  • 누이터에 에러메시지 적용하기
    -> 파이어베이스 기능으로 해결 가능

4. 에러와 에러 메시지를 파이어베이스로 처리하기

  • Auth.js

    -> 에러를 관리하기 위한 상태 생성
    -> 에러 발생 지점setError 함수 사용하면 됨
    -> 무슨 메시지를 담을까?

5. 일부러 중복 회원가입 에러 발생시켜 보기

: try-catch 문으로 중복 회원가입 시, error 출력
-> 우리가 원하는 메시지가 아닌, 파이어베이스의 기능

6. error.message 화면에 출력하기

: 실제 우리가 원하는 에러 메시지는 error.message에 담겨있음
-> setError 함수에 error.message를 전달해서 error 상태 변화시킴



-> {error}에 의해서 error의 상태가 화면에 출력되고 있음을 알 수 있따.

---> 로그인 에러 작업 처리하기! (중복회원가입....etc)

7. 로그인/회원가입 토글 버튼 적용하기

  • 토글버튼: 2가지 내용이 번갈아 바뀌는 버튼
    -> 로그인 여부에 따라 로그인/회원가입 전환되도록
  • Auth.js


    -> 코드를 위와 같이 수정
    -> setNewAccount 함수에 (prev) => !prev 함수 전달
    -> 함수를 인자로 전달하면, 인자로 전달한 함수의 1번째 인자에 이전의 상태가 넘어와(prev)
    -> false 이었으면 눌렀을 때 true이 되므로, "Sign In" 출력 (즉, 이미 계정 있으면, 1로 바뀌면서, Sign in)

    -> sign in 누르면 버튼도 로그인버튼으로 바뀌는 것을 알 수 있음!!

---> 여기까지는, 파이어베이스 로그인 기능 연동시키고, 회원가입과 동시에 로그인 기능 구현/또 에러 처리 완료. 토글버튼 적용까지! (로그인 실패 시, 계속 Auth 컴포넌트 띄어줌)

😀 누이터에 소셜 로그인 추가하기

: 파이어베이스의 signWithPopup 함수 이용

1. 소셜 로그인 버튼에서 name 속성 사용하기

: event.target.name 속성을 사용하여 구글/깃허브 로그인 구별

  • Auth.js 파일 수정


    -> 코드를 위와 같이 수정
    -> 버튼 클릭 시, console에 나타남 (name 속성)

    -> 버튼 클릭 때마다, 콘솔 창에 위와 같이 나타남!

2. 소셜 로그인을 위해 firebaseInstance 추가하기

: authService에는 소셜 로그인에 필요한 provider가 없음
-> firebase에 들어있으므로 import 해야 함
-> firebaseInstatnce라는 이름으로 export
-> import, export 수정 후에는 서버 재시작 해야함!

  • fbase.js

3. provider 적용하기

  • Auth.js

    -> firebaseInstance import 잊지말기!

    -> 각 로그인 버튼 클릭 시, onClick props에 onSocialClick 함수를 지정해서 구글이면 구글 소셜 로그인 함수, 깃허브면 깃허브 실행하도록!
    -> provider: 소셜 로그인 서비스 제공 업체 대입
    : 소셜 로그인 처리할 signWithPopup 함수 가지고 이씀

4. 소셜 로그인 완성

: signWithPopup 함수 이용해서 소셜 로그인 완성

-> signWithPopup: 비동기 작업이므로 async-await문 사용
-> provider를 인자로 전달

---> 여기까지는 소셜로그인 성공

😀 내비게이션 추가하고 로그아웃 처리하기

: 사이트 옮겨다니도록

1. 내비게이션 컴포넌트 만들고 라우터에 추가하기

: 내비게이션 컴포넌트-> 라우터가 제어
-> 대부분의 페이지에 보여야 함 (components 폴더에)

-> components 폴더에 파일 생성해서 위와 같이 코드 작성

  • Router.js

    -> 내비게이션 컴포넌트 만들고 라우터와 연결
    -> Switch에 포함 X: Switch에 포함된 Route중 하나만 보여주므로! 위에 배치해서 모든 페이지에서 보이도록
    -> 회원가입이나 로그인 페이지에서는 내비게이션 보일 필요없음 (isLoggedIn이 true인 경우에만 Navigation 보이도록 처리)
    -> && 왼쪽 조건이 true이면 오른쪽에 있는 값 반환

    -> 로그인 상태인 경우에만 Navigation이 보임을 알 수 있다.

2. 내비게이션에 링크 추가하기

: 링크는 'react-router-dom'의 'Link' 사용

  • Navigation.js

    -> Home, Profile 컴포넌트로 이동할 수 있도로 nav 뼈대 생성

    -> My profile 눌러도 컴포넌트 렌더링 x (링크는 이동)
    : Router가 Home, Auth 컴포넌트에 대한 분기만 처리하고 있어서!
    즉, 링크 이후 그 화면까지 보이게 하려면, 링크이동과 라우터 통한 컴포넌트 렌더링도 해주어야 함!

    -> 로그인 상태이면, Navigation 컴포넌트가 수행된다. Home을 누르면, /링크로 이동하고 My profile을 누르면 profile 파일 링크로 이동한다. 그런데, 링크 이동 후, 렌더링은 라우터에 의해 일어남. NAVIGATION에서의 링크에 따라서!

    -> 이와 같이 Profile 컴포넌트 렌더링

---> 여기까지, 로그인 상태이면 home, profile 페이지 왔다갔다하기

3. 로그아웃까지 깔끔하게 마무리하기

: <로그아웃> 버튼 만들기 (authService의 signOut함수 이용)
-> Profile 컴포넌트에

-> onClick props로 onLogOutClick 함수 적용 (signOut 함수 실행)
-> Indexed DB 정보 비우고, 로그아웃까지
-> isLoggedIn의 값: false로

-> 로그아웃했는데, 여전히 주소는 '/profile'
-> 주소 이동 방법 2가지를 배워보자(4,5번)

4. Redirect로 로그아웃 후 주소 이동하기


-> 코드를 위와 같이 수정
-> 마지막 Route 다음에 Redirect 배치하여, Route 조건들이 모두 맞지 않는 경우, Redirect가 지정한 곳으로 주소 이동

  • Redirect: from 프롭스에 있는 값을 조건으로 해서 to 프롭스에 있는 값으로 주소 이동

-> 로그아웃하면 isLoggedIn이 상태가 false일 때의 Route가 동작. 그런데, 정확하게 주소가 "/"인 경우에만 해당
-> but, 로그아웃 후에는 "/profile"임.
-> 따라서 마지막 Route까지 무시하고, Redirect 동작

-> 따라서 로그아웃 누르면 여기로 되돌아온다. (isLoggedIn이 false이고 '/'로 돌아오는 것이다.
-> '/'는 http://localhost:3000 으로 돌아온다는 뜻! 즉 처음페이지로 돌아온다. 처음페이지는 isLoggedIn 상태일 때는 Router.js에 의해서 Auth 컴포넌트가 실행될 것이다!!!

✔️ 왜 redirect 했을 때, to하면 로그인 페이지로 돌아오는 지 이해가 안되었음. 구글링을 통해 redirect의 의미를 공부하면서 '/'로 돌아온다는 뜻이 http://localhost:3000로 돌아온다는 뜻임을 알고 코드 이해함.
-> 코드 명확히 이해되고 나니 통쾌...

5. useHistory로 로그아웃 후 주소 이동하기

: 로그아웃 처리하는 js코드 마지막에 처음 화면으로 이동하라는 명령 (useHistory-push 통해서)

  • history: 브라우저에서 사용자의 주소 이동 발자취를 기록 (뒤로가기, 새로고침 가능)
  • useHistory: 리액트에서 브라우저의 history사용할 수 있게
  • Profile.js

    -> 'history.push("/");'

⭕ 정리:
이번 장에서는 파이어베이스 인증 기능을 사용하기 위해 파이어베이스와 연동하고, auth 모듈을 불러오는 작업을 하였다. 그리고 이메일/비번 로그인, 소셜로그인을 구현하기 위해서 파이어베이스에서 각 사이트에 접근 권한을 받아오는 것을 설정하였다. 그리고 로그인 폼 구조를 만들었다. 여기까지 로그인 서버가 준비되었고, 로그인 준비가 끝났다.
1. 이메일/비밀번호 인증 기능

  • 파이어베이스의 함수를 이용하여 회원가입 처리 (자동으로 로그인)
  • 정보는 indexed db에 저장
  • 로그인 처리 (isLoggedIn true로 바꾸기 위해 useEffect함수 사용)
  • 에러 메시지 처리(중복 회원가입..)
  • 토글버튼-회원가입/로그인 버튼 바뀌게
  1. 소셜 로그인
  • firebaseInstance의 provider 사용
  • signWithPopup 함수 사용하여 로그인
  1. 내비게이션 추가, 로그아웃
  • 로그인 상태: home, profile 화면 이동하도록
  • profile에서는 로그아웃 가능하게
  • 로그아웃: 로그아웃 버튼 누르면 처음 화면으로 되돌아가도록 (주소 이동 방법 2가지-redirect, useHistory.push)

----> 이번 장은 특히 어렵고 중요한 내용들이 많으니까 복습 꼼꼼히 하기!!

profile
지수의 취준, 개발일기
post-custom-banner

0개의 댓글