: 파이어베이스 인증기능 연동 (로그인 과정)
: useState(상태) app.js로 옮기기 (상태 App 컴포넌트에서 관리)
-> AppRouter: 라우터 역할, 코드의 가독성
-> 밑줄 친 부분은 현재 연도를 반환해주는 자바스크립트 함수 (footer 엘리먼트에 올해 연도 출력)
-> jsx에서 함수를 사용하려면 중괄호
-> ©: jsx에서 copyright 기호 출력
-> app.js와 Router.js를 위와 같이 수정해준다.
-> index.js에서 app.js를 불러온다. 그 후 AppRouter을 isLoggedIn의 상태와 함께 컴포넌트를 렌더링한다. 그랬더니, false이므로 Auth 컴포넌트가 실행되고, footer에 의해서 현재 연도와 글자가 출력된다.
-> import 문 사용 시, 위는 상대 경로를 사용!
-> 가독성 떨어짐
-> 절대 경로로 바꿔보자
: 상대 경로로 설정된 곳 절대 경로로 바꾸기
-> import 문 수정 후에는, 서버 다시 시작해야 화면 제대로 출력!! (ctrl+c -> npm run start)
-> 코드의 import 부분들을 아래와 같이 수정해준다.
파이어베이스 특징:
특정 모듈 사용 시, 모듈 추가로 불러와야 함
-> 인증 모듈 사용하기 위해서: 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번 실행된다. 오류를 더 쉽게 포착
: 이메일/비번 기반 로그인, 구글, 깃허브 소셜 로그인 누이터에 적용하기
-> 파이어베이스 콘솔에 접속해서 파이어베이스 기본 설정
-> 이메일/비밀번호에서 위와 같이 설정해준다.
-> 구글 로그인도 위와 같이 설정해준다. 공개용 이름은 그대로 두고, 지원 이메일에는 기본값 설정해준다.
-> 아이디, 비번 입력후, 링크를 복사한 후 저장을 누른다.
-> 깃허브에 접속하여 로그인 관련 설정을 해줄 것이다.
-> developer settings에 들어가준다.
-> oAuth apps -> register a new application
(oAuth: 다른 사이트의 계정 정보의 접근 권한만 받아 해당 계정을 이용해 로그인할 수 있게 해주는 기능, 사용자에게 별도의 아이디와 비번을 요구하지 않음)
-> homepage URL은 아까 firebase 홈페이지에서 승인된 도메인에서 'firebase.com으로 끝나는 주소 앞에 http://를 붙여서 적어준다.
-> 그 아래 URL은 아까 복사한 주소를 넣어준다.
-> client id를 복사해서 아까 그 페이지로 돌아가 클라이언트 id에 넣어준다.
-> 여기서 비밀번호를 생성해 아까 그 페이지로 돌아가 클라이언트 보안 비밀번호에 적어준다.
: Auth.js에 로그인을 위한 폼 생성
-> 위와 같이 Auth.js 파일을 수정해준다.
-> 그러면 위와 같이 폼이 나타난다.
-> 구글, 깃허브 소셜 로그인은 파이어베이스 서버에 로그인 요청만 하면됨! (아까 그 사이트들에 대한 접근 권한을 허용받았음)
폼이 실행되게 하려면?
: useState 함수로 상태 만들어주고, onChange, onSubmit 함수로 이벤트 연결해줘야 함
-> Auth 파일을 위와 같이 수정해준다.
-> 폼에 입력을 시도해보면, input element의 name 속성에 지정한 값이 출력됨을 알 수 있다. event.target.name을 통해 어떤 엘리먼트에 입력을 시도하고 있는지 구분할 수 있음
-> 상태를 업데이트하도록 위와 같이 코드를 다시 수정
-> event.target에서 name, value 값을 가져와서 name에 따라 이메일과 비밀번호 정보를 업데이트하도록 하였다.
: 회원가입 기능과 인증 기능
-> 파이어베이스에서 제공하는 기능
-> 위와 같이 코드를 수정
-> newAccount로 상태를 관리하여, 그 값에 따라 회원가입/로그인을 할 수 있도록 분기
: 파이어베이스 적용
-> EmailAuth Provider에 속한 CreateUserWithEmailAndPassword(인자로 전달받은 이메일, 비번을 파이어베이스 DB에 저장) 함수와 signInWithEmailAndPassword(인자로 받은 이메일, 비번을 데이터베이스에 전달하여 확인 후 로그인) 함수 사용
-> authService에 그 함수들 포함
-> 위와 같이 Auth.js 파일을 수정
-> async, await: 서버로 값을 요청해서 결괏값을 수신 받기까지 시간 소요/ 인증 처리 이후 누이터 실행되어야 하므로 기다렸다 실행하라
-> try, catch: 로그인 또는 회원가입의 성공과 실패 처리
async, await: 비동기를 동기처럼 보이게
-> try, catch로 에러 핸들링 가능
-> 위의 코드에서는, 알아서 순서대로 처리하지만, 인증 처리 이후 누이터 실행하도록 명시 중
로그인을 지속시켜주는 setPersistence
: 3가지로 나누어 로그인 상태 관리
: local 옵션으로 저장한 로그인 정보는 어디에 저장?
-> 브라우저 내의 Indexed DB에 저장
-> 개발자 도구의 application-> indexed db에서 사진 속의 경로에 내가 회원가입 시 입력한 이메일이 들어있음을 알 수 있다.
-> indexed db에 저장하기 위한, 코드를 따로 적어주지 않았지만, 파이어베이스에 의한 자동으로 잘 저장!
: 앞서 배운 회원가입과 즉시 로그인, 정보 저장 기능을 누이터에 적용
: 비동기 처리이기 때문! (신호 보냄-> 받음-> 처리 순서대로!) but, 처리 과정 생략
-> 로그인 처리 이후, 누이터에서 신호받기까지 시간 간격 (신호 받은 이후 화면에 출력해줘야 함. 비동기이므로)
-> 요청은 보냈지만, 데이터를 기다리고 있지 않음
-> 리액트 생명주기를 통해 해결
: setInterval(밀리초 단위) 함수 (신호 받기까지의 걸리는 시간 확인)
-> 2번째 인자의 시간 간격마다 1번째 인자의 코드 실행
-> authService.current를 2초마다 실행하여 로그인 처리 완료까지의 시간 계산
: 특정 시점에 실행되는 함수
-> 파이어베이스 로그인 정보를 받게 되었을 때
-> currentUser가 변경되는 시점을 알기위해(console에 null이 아닌 객체를 제대로 출력하기 위해-항상 로그인 되어있지 않은 것으로 표시되는 것을 해결)
-> useEffect로 로그인 정보 받게된 시점 잡아낸 후, 보여줄 화면 렌더링
-> 파이어베이스의 onAuthStateChange함수 이용
---> 인증 상태 감지: onAuthStateChange, useEffect
-> 밑줄친 부분과 useEffect를 수정
-> 2번째 인자를 []로 지정해야 컴포넌트가 최초로 렌더링이 완료되었을 때, 1회만 동작
-> useEffect 함수에 의해, 컴포넌트 렌더링 이후 인증 상태 출력
-> 초반엔 로그인이 안되어있으므로 false이고, 회원가입 시, 자동으로 로그인되어, 그 후로 인증 상태가 감지되는 경우에만, 그 값이 전달되어 참이므로 home 컴포넌트가 실행된다. 그렇지 않으면, false가 되어 Auth 컴포넌트 실행!
: indexed DB를 clear (수동)
-> 다시 회원가입 창으로 돌아옴
-> 로그아웃은 소셜 로그인 배운 이후에 다시!
: try-catch 문으로 중복 회원가입 시, error 출력
-> 우리가 원하는 메시지가 아닌, 파이어베이스의 기능
: 실제 우리가 원하는 에러 메시지는 error.message에 담겨있음
-> setError 함수에 error.message를 전달해서 error 상태 변화시킴
-> {error}에 의해서 error의 상태가 화면에 출력되고 있음을 알 수 있따.
: 파이어베이스의 signWithPopup 함수 이용
: event.target.name 속성을 사용하여 구글/깃허브 로그인 구별
: authService에는 소셜 로그인에 필요한 provider가 없음
-> firebase에 들어있으므로 import 해야 함
-> firebaseInstatnce라는 이름으로 export
-> import, export 수정 후에는 서버 재시작 해야함!
: signWithPopup 함수 이용해서 소셜 로그인 완성
-> signWithPopup: 비동기 작업이므로 async-await문 사용
-> provider를 인자로 전달
: 사이트 옮겨다니도록
: 내비게이션 컴포넌트-> 라우터가 제어
-> 대부분의 페이지에 보여야 함 (components 폴더에)
-> components 폴더에 파일 생성해서 위와 같이 코드 작성
: 링크는 'react-router-dom'의 'Link' 사용
: <로그아웃> 버튼 만들기 (authService의 signOut함수 이용)
-> Profile 컴포넌트에
-> onClick props로 onLogOutClick 함수 적용 (signOut 함수 실행)
-> Indexed DB 정보 비우고, 로그아웃까지
-> isLoggedIn의 값: false로
-> 로그아웃했는데, 여전히 주소는 '/profile'
-> 주소 이동 방법 2가지를 배워보자(4,5번)
-> 코드를 위와 같이 수정
-> 마지막 Route 다음에 Redirect 배치하여, Route 조건들이 모두 맞지 않는 경우, Redirect가 지정한 곳으로 주소 이동
-> 로그아웃하면 isLoggedIn이 상태가 false일 때의 Route가 동작. 그런데, 정확하게 주소가 "/"인 경우에만 해당
-> but, 로그아웃 후에는 "/profile"임.
-> 따라서 마지막 Route까지 무시하고, Redirect 동작
-> 따라서 로그아웃 누르면 여기로 되돌아온다. (isLoggedIn이 false이고 '/'로 돌아오는 것이다.
-> '/'는 http://localhost:3000 으로 돌아온다는 뜻! 즉 처음페이지로 돌아온다. 처음페이지는 isLoggedIn 상태일 때는 Router.js에 의해서 Auth 컴포넌트가 실행될 것이다!!!
✔️ 왜 redirect 했을 때, to하면 로그인 페이지로 돌아오는 지 이해가 안되었음. 구글링을 통해 redirect의 의미를 공부하면서 '/'로 돌아온다는 뜻이 http://localhost:3000로 돌아온다는 뜻임을 알고 코드 이해함.
-> 코드 명확히 이해되고 나니 통쾌...
: 로그아웃 처리하는 js코드 마지막에 처음 화면으로 이동하라는 명령 (useHistory-push 통해서)
⭕ 정리:
이번 장에서는 파이어베이스 인증 기능을 사용하기 위해 파이어베이스와 연동하고, auth 모듈을 불러오는 작업을 하였다. 그리고 이메일/비번 로그인, 소셜로그인을 구현하기 위해서 파이어베이스에서 각 사이트에 접근 권한을 받아오는 것을 설정하였다. 그리고 로그인 폼 구조를 만들었다. 여기까지 로그인 서버가 준비되었고, 로그인 준비가 끝났다.
1. 이메일/비밀번호 인증 기능
----> 이번 장은 특히 어렵고 중요한 내용들이 많으니까 복습 꼼꼼히 하기!!