티스토리 뷰






1) Authentication 콘솔 설정

Firebase Authentication을 사용하여 가입 및 로그인 처리를 해보겠습니다. 

 Authentication 을 사용하기 위하여 Firebase Console화면으로 진입한 후 좌측 Authentication 메뉴에 들어가고, 그 다음 로그인 방법 탭으로 들어갑니다.

로그인 방법 탭 항목 중 이번 예제에서는 '이메일/비밀번호', 'Google',  'Facebook' 항목을 이용하겠습니다. 



'이메일/비밀번호' 라인을 클릭해봅니다. 그러면 아래와 같은 팝업창이 뜹니다. 사용설정 스위치버튼을 눌러 사용설정을 해줍니다. 'Google'도 마찬가지로 사용설정을 해줍니다.




Facebook 설정은 Facebook 로그인과 Firebase Authentication을 연결지어 주기 위하여 사용 설정을 하기 전에 Facebook 개발자 사이트에서 설정이 필요합니다. 아래의 링크를 방문해주세요.




만약에 Facebook계정이 없다면 Facebook 계정이 필요합니다. 해당 사이트 로그인 후 우측 상단에 내 앱 > 새 앱 추가를 누르고 간단하게 명칭을 지어주고 이메일을 입력한 뒤 '앱 ID 만들기' 버튼을 눌러줍니다.



Facebook 개발자 콘솔 화면이 나옵니다. 여기서 Facebook 로그인을 마우스를 올려보면, 설정버튼이 있는데 설정 버튼을 눌러 줍니다.



설정을 누르면 좌측화면에 'Facebook 로그인' 메뉴가 생성이 됩니다. 그 아래에 설정으로 들어가 주세요. 



설정으로 들어가면 '유효한 OAuth 리다이렉션 URI' 라는 항목이 있습니다.이 때 Firebase에서 알려주는 URI 입력이 필요한데 Firebase console 화면에서 Authentication > 로그인 방법 > Facebook을 클릭하면 뜨는 팝업화면 아래에 있는 정보를 복사하여  '유효한 OAuth 리다이렉션 URI' 항목에 입력하고, 아래쪽 변경 내용 저장 버튼을 눌러 값을 저장해 줍니다.




Facebook 앱은 처음 생성하게 되면 개발 모드 상태입니다.  이는 로컬호스트에서 테스트 때만 정상 작동하므로 배포시 정상 작동하게 하기 위해서 앱을 공개해야합니다. 좌측 메뉴 앱 검수 메뉴에서 앱을 공개해주세요.



Facebook 개발자 콘솔 화면에서의 설정은 완료되었습니다. 대시 보드에 있는 '앱 ID'와 '앱 시크릿 코드' 정보를 Firebase console 화면에 입력이 필요합니다.



다시 Firebase 콘솔로 진입하여 Facebook 개발자 콘솔에서 획득한  '앱 ID'와 '앱 시크릿 코드' 를 입력하고 사용 설정을 켜줍니다.



나중에 로그인 코드가 완성이 되고 로그인을 하게 되면 아래와 같은 로그인 화면이 팝업으로 뜨게 됩니다.




2)  구글 계정으로 가입 및 로그인 작성

프로젝트 소스에서 public/index.html  파일을 열고 소스 아래쪽 script 태그 안에서 아래의 코드를 작성하고, 콘솔 또는 명령프롬프트 창에서 firebase serve명령어를 입력하여 결과화면을 보기위해 http://localhost:5000 으로 들어갑니다.
firebase serve




FirebaseChat 클래스의 생성자 안에 init메소드와 initEvent 메소드가  있습니다. init 메소드는 클래스가 인스턴스로 생성이 될때 할당될 변수들을 선언해두는 곳이고, initEvent는 초기에 바인딩할 이벤트들을 모아두었습니다. 

화면에서 '구글 계정으로 가입 및 로그인' 버튼을 누르면 onGoogleBtnClick 메소드가 실행됩니다. Firebase Authentication라이브러리가 제공하는 팝업을 띄우며 로그인하는 signInWithPopup 메소드가 실행이 되며 구글 로그인 화면이 나옵니다.

브라우저 개발자 도구를 통해 잠시 Console 로그를 살펴보겠습니다.

화면을 띄우면서 로그인을 아직 하지 않은 상태이므로 onAuthChange 메소드에 user값이 null이 들어와서 Console에 '로그아웃'이 찍힙니다.

그리고 '구글 계정으로 가입 및 로그인' 버튼을 눌러 로그인을 하게되면 먼저 signInWithPopup 프로미스 결과 값으로 then에서 '로그인 성공' 이 먼저 찍히고, 그 다음 onAuthChange 함수에서 user 값이 들어오며 Console 화면에서 user 로 들어오는 정보가 찍히게 됩니다. JSON 형태로 들어오므로 stringfy함수로 해당 데이터를 print 하였습니다. 

user정보에서 uid 는 프로젝트에 가입한 고유한 id 값이며, displayName 은 provider(구글, 페이스북 등등) 에서 제공받은 사용자 이름이며, photoURL은 provider에서 제공 받은 이미지이며, email 은 가입한 email정보 입니다. emailVerified는 사용자 확인 여부 입니다. emailVerified 값은 구글 또는 페이스북 같은 provider를 통해 가입한 유저는 true 로 들어오며, 이메일 가입 유저의 경우는 가입 직후는 false로 들어오며, Firebase 에서 전송된 이메일 주소 인증 메일을 인증하게 되면 true 값이 들어오게 됩니다.

그 이외에도 많은 다양한 정보들이 user정보에 포함되어 들어오는 것을 알 수 있습니다.




이제 브라우저를 닫고 다시 한번  http://localhost:5000  으로 들어갑니다. 다시한번 브라우저 개발자 도구의 콘솔 창을 확인해봅니다.




로그인 버튼을 누르지 않았음에도 불구하고 onAuthChange 메소드에서 user값이 찍히는 것을 볼 수 있습니다.  어떻게 된 것 일까요? Authentication 에서는 인증상태 지속 유형이 3가지로 나뉘는데 그 중에 기본 값이 local 상태 입니다. local 상태는 브라우저가 닫혀도 로그인 값을 브라우저내에 저장하고 있습니다. 명시적으로 로그아웃하거나 브라우저 캐시를 지워야지만 로그인이 제거 됩니다. 상태 값의 3가지 내용은 아래와 같습니다.

열거형
설명
firebase.auth.Auth.Persistence.LOCAL
'local'
브라우저 창이 닫히거나 React Native에서 활동이 폐기된 경우에도 상태가 유지됨을 나타냅니다. 이 상태를 삭제하려면 명시적으로 로그아웃해야 합니다. Firebase 인증 웹 세션은 단일 호스트 출처이며 단일 도메인의 경우에만 유지된다는 점에 유의하세요.
firebase.auth.Auth.Persistence.SESSION
'session'
상태가 현재 세션이나 탭에서만 유지되며 사용자가 인증된 탭이나 창이 닫히면 삭제됨을 나타냅니다. 웹 앱에만 적용됩니다.
firebase.auth.Auth.Persistence.NONE
'none'
상태가 메모리에만 저장되며 창이나 활동이 새로고침되면 삭제됨을 나타냅니다.

앱을 만들때 적절하게 선택이 필요합니다. 이번 예제에서는 브라우저를 닫으면 로그아웃 되는 상태로 만들고자합니다. 그렇게 하기 위해서는 onGoogleBtnClick 메소드에 변화를 주겠습니다.




onGoogleBtnClick 메소드 안에 Authentication 메소드 setPersistence 메소드를 사용하여 지속성을 설정합니다. 브라우저가 닫힐 때 로그아웃을 위해 firebase.auth.Auth.Persistence.SESSION 값을 줍니다.

signInWithPopup 메소드를 FirebaseChat클래스에 추가하였습니다. 다른 Provider로그인에서 공통으로 사용하기 위함입니다.

3) 페이스북 계정으로 가입 및 로그인 작성

페이스북 로그인 기능을 구현하기 위해 아래의 코드를 입력합니다.




FirebaseChat클래스의 init 메소드에 페이스북 계정으로 가입 및 로그인' 버튼의 엘리먼트를 할당할 변수를 추가합니다. initEvent 메소드에는 페이스북 버튼의 클릭 이벤트리스너를 추가합니다. 그리고 페이스북 버튼의 클릭리스너의 콜백 메소드인 onFacebookBtnClick 메소드를 추가합니다. onFacebookBtnClick 메소드는 onGoogleBtnClick 기능은 동일합니다. 다만 할당 받는 Provider만 다릅니다.

3) 일반 이메일로 가입

구글과 페이스북 로그인의 경우 유저 정보를 로그인 인증을 해주는 업체에서 제공을 받지만, 일반 이메일은 가입 폼을 따로 작성하여 가입처리를 해주어야 합니다. 화면은 미리 구성 해놓았습니다. '이메일으로 가입' 버튼을 누르면 현재 보이는 로그인 화면은 숨기고, 숨겨져있는 가입 영역인 dvJoin 아이디를 가진 div 영역을 보이게 합니다.  아래의 코드를 추가해주세요.






'이메일으로 가입' 버튼을 누르면 위 화면이 나옵니다. 이제 기입되는 정보를 바탕으로 가입처리를 하겠습니다. 가입처리 전에 유효성 검증도 필요할 것입니다. 아래 코드를 입력하십시오.




위 메소드 들은 이메일 가입 폼에서 '이메일으로 가입' 버튼을 누르게되면 진행되는 메소드 들입니다. 버튼을 누르면 createEmailUser 메소드가 실행이 되고, 메소드 안에서 validateJoinForm 메소드를 통해 유효성 검증을 합니다. validateJoinForm 메소드안에서 이메일 형식과 비밀번호와 비밀번호 확인 데이터가 같은지 검증을 하게 됩니다. 

createEmailUser 하단을 보면 다른 로그인 처리하는 것과 같이 지속성 설정이 되어 있고, 그 후 콜백으로 createUserWithEmailAndPassword메소드를 실행하여 가입처리를 진행하도록 되어 있습니다. createUserWithEmailAndPassword메소드를 실행되면 프로미스를 반환받고 프로미스가 reject되게 되면 .catch 메소드에서 콜백을 수행하게 됩니다. catch메소드 의 콜백에는 4종류의 에러코드를 반환하는데 이에 따른 분기 처리 코드가 들어가 있습니다.

이제 화면을 띄우고 이메일 가입을 수행하여, console 로그 정보를 잠시 살펴보겠습니다.



이메일 가입 성공 로그가 찍히며 user 정보를 반환합니다. 그리고 가입 동시에 로그인 처리가되며 onAuthChange에도 user정보가 찍히는 것을 볼 수 있습니다.
이메일 가입 성공 후 로그를 살펴보면 displayName에 Null이 들어가있습니다. 안타깝게도 이메일 가입을 위한 Firebase에서 제공하는 createUserWithEmailAndPassword의 패스워드의 파라미터는 이메일과 패스워드 정보만 받기 때문입니다. 이메일로 가입 성공 후 실행되는 then메소드 안에 콜백 함수 user정보를 통해 프로필을 업데이트 시킬 수 있습니다. createEmailUser 메소드를 수정해보겠습니다.




다시한번 가입 테스트를 수행하기 위해 브라우저를 다시 실행하여 가입을 수행해봅니다. 만약에 수행할 다른 이메일이 없으시다면 Firebase console로 들어 가셔서 Authentication화면으로 들어가면 아래와 같이 유저를 관리할 수 있는 컨텍스트 메뉴가 있습니다.  유저를 제거 하시고 가입테스트 하시면 되겠습니다.



다시 가입 직후에는 아직 update된 displayName이 보이지 않지만, 새로고침을 해보면 아래와 같이 displayName에 이름이 들어간 것을 확인할 수 있습니다.



displayName은 갱신이 되었지만, 아직 유효한 이메일인지 여부를 알려주는 값은 여전히 false로 남아 있습니다. 이메일 가입성공 시 이메일 주소 인증 메일을 보낼 수 있습니다.
다시한번 createEmailUser 메소드를 수정하겠습니다.




sendEmailVerification 메소드로 가입 성공 후 유효한 이메일인지 확인하는 확인 메일을 전송 합니다. Firebase 기본값은 영어 메일로 되어 있습니다. useDeviceLanguage메소드를 앞서 실행해줌으로써 디바이스 또는 브라우저의 언어로 설정되어져 메일이 전송이 됩니다. 

+ 메일이 구글 사정에 따라 전송되는데 시간이 걸릴 수 있습니다.



만약 전송되는 메일의 포맷을 변경하고자한다면 Firebase console 으로 진입하여 Authentication메뉴에 템플릿 탭을 확인해주세요. 아래와 같이 이메일 주소 인증 메일 뿐만 아니라 비밀번호 재설정 메일, 이메일 주소 변경 메일 등을 설정할 수 있고, 기본 발송 언어 또한 설정할 수 있습니다.




작성할때 맞춤 메일을 작성하기 위해 미리 정해진 자리표시자 문자열을 사용하여 발송 전에 입력될 값을 나타낼 수 있습니다.
%FIRST_NAME%
수신자의 이름
%APP_NAME%
앱의 이름. 설정 페이지에서 공개용 이름 필드를 수정하여 이 값을 설정할 수 있습니다.
%LINK%
계정 관리 작업을 완료하기 위해 수신자가 방문해야 하는 URL. 작업 링크 URL 맞춤설정을 참조하세요.
%EMAIL%
수신자의 이메일 주소
%NEW_EMAIL%
수신자의 기본 주소로 설정할 새 이메일 주소. 이메일 주소 변경 템플릿에만 사용됩니다.

4) 일반 이메일로 로그인

이제 가입한 일반 이메일로 로그인하는 부분의 코드를 작성해보겠습니다. '이메일으로 로그인' 버튼에 이벤트를 바인딩하고 로그인을 실행하겠습니다. 다음 코드를 추가해주세요.



'이메일으로 로그인'을 클릭 시 수행할 메소드로 onEmailBtnClick을 작성하였습니다. onEmailBtnClick를 살펴보면, 이메일 유효성 검증과 패스워드입력여부를 판단 한 후 다른 provider로그인과 마찬가지로 지속성 설정을 SESSION으로 설정한 이후 로그인 처리를 하였습니다. 그리고 이메일 로그인 메소드인 signInWithEmailAndPassword메소드의 catch부분에서 에러코드 별로 분기 처리가 되어 있습니다.

5) 로그인 후 화면 이동

로그인 후 화면 이동 처리는 각 개별 로그인 메소드에서 처리해도 되나, 한 곳에서 처리하기 위해 인증상태 변화를 감지하는 onAuthChange 메소드를 통해 처리하도록 하겠습니다. onAuthChange 메소드를 아래와 같이 수정하고, 로그인일 때와 로그아웃일때 동작을 정의하는 메소드를 추가해주세요.




onAuthChange 메소드가 수정되었으며, setLogin과 setLogOut메소드가 추가되었습니다.  onAuthChange를 통해 인증변화 감지에서 user 정보가 넘어오면 로그인 화면을 숨기고, 채팅앱의 본화면으로 전환하는 코드가 들어가있습니다. 반대로 user 정보가 넘어오지 않으면 채팅화면을 숨기고, 로그인 화면으로 돌아가도록 코드가 작성되어져 있습니다.

그리고 setLogin메소드를 보면 firebase의 database 객체를 필드 변수에 할당하는 코드가 들어가 있습니다. Firebase Realtime Database의 경우에 기본 값으로 Authentication을 통해 인증 받은 사용자만 읽기와 쓰기 권한을 가지도록 설정되어있습니다.  database.rules.json 파일을 열어봐주세요.



database 객체를 FirebaseChat클래스가 생성이 될 때 할당이 된다면, 즉 Authentication인증 받기 전에 database를 할당 받고, 읽거나 쓰기 작업을 시작하면 권한 오류가 발생합니다.



그리고 setLogin메소드에서는 goOnline메소드가 logOut 메소드에서는 goOffline메소드가 있습니다. goOnline메소드는 연결을 재설정하고 동기화 하며, goOffline메소드는 연결된 데이터베이스 모두 연결을 해제합니다. Firebase Realtime Database의 경우 연결 커넥션 수와 자원을 아끼기 위해 로그아웃이 되면 명시적으로 연결을 해제하였습니다. 그리고 뒤쪽에서 설명될 접속 유저를 판별하기위해서 로그아웃 직전에 명시적으로 데이터를 끊을 필요가 있습니다.

6) 로그아웃 기능

로그인기능을 통해 화면에 진입을 할수 있게 되면 아래쪽에 3개의 탭이 있습니다. 그 중 톱니바퀴 모양의 3번째 설정 탭을 클릭해보면 로그아웃 기능을 위한 버튼이 준비되어 있습니다. 여기에 이벤트를 바인딩 하도록 하겠습니다.



아래 코드를 입력해주세요.




이제까지 Firebase Authentication의 주요 기능을 활용하여 로그인과 로그아웃 기능을 구현하였습니다. 가입한 유저들을 목록으로 불러오려면 우선 가입하는 시점에서 데이터베이스에 저장을 해야합니다.  Firebase Realtime Database를 활용하여 유저 저장, 유저 리스트 불러오기, 채팅방 구현 등의 기능들을 구현해보겠습니다.


챕터 완성 소스 :





  1. 예제 소개
  2. Firebase 설정하기
  3. Hosting을 활용한 프로젝트 준비 작업
  4. Authentication을 이용한 유저 가입 및 로그인 구현하기
  5. Realtime Database를 이용한 채팅기능 구현 - Reatime Database 특징 및 데이터 구조
  6. Realtime Database를 이용한 채팅기능 구현 - 유저데이터 저장하기
  7. Realtime Database를 이용한 채팅기능 구현 - 유저리스팅 화면
  8. Realtime Database를 이용한 채팅기능 구현 - 채팅화면 및 채팅메세지 리스팅
  9. Realtime Database를 이용한 채팅기능 구현 - 채팅메세지 전송기능
  10. Realtime Database를 이용한 채팅기능 구현 - 채팅방 리스팅화면
  11. Realtime Database를 이용한 채팅기능 구현 - 채팅방 초대 기능
  12. Realtime Database를 이용한 채팅기능 구현 - 접속 중인 유저 표시하기
  13. Storage를 이용한 파일 전송기능
  14. Cloud Messaging과 Functions을 이용한 푸시메세지 기능 - FCM Token 정보 저장
  15. Cloud Messaging과 Functions을 이용한 푸시메세지 기능 - Functions를 통한 FCM 발송
  16. Cloud Messaging과 Functions을 이용한 푸시메세지 기능 - Service worker를 이용한 FCM수신
  17. Realtime Database 권한 설정

 



댓글
  • 프로필사진 안녕하세요 안녕하세요, 글 잘 보고 있습니다!

    중간에 유저 이름을 받아 업데이트 하는 과정에서

    user.updateProfile({
    displayName: this.userName
    })

    이렇게 되어 있는데

    user.updateProfile({
    displayName: userName
    })

    처럼 this를 빼줘야 하지 않을까요?
    2018.04.15 10:11 신고
  • 프로필사진 구독자1 안녕하세요, 좋은 글 감사합니다.

    궁금한게 있습니다만,

    현재 auth 부분만 깃헙에서 클론해서 바로 deploy 하려면 어떻게 해줘야 되나요 ?

    처음부터 firebase init 과정부터 진행을해야되는건가요 ?

    ㅠㅠ
    2018.05.01 17:02 신고
  • 프로필사진 ㄷㄷ 앱이 개발 모드 상태이므로 일부 사용자만 이용할 수 있습니다.

    이 부분을 공개로 바꾸라고 하셨는데요
    공개로 바꾸려고 눌러보니

    "앱을 라이브 상태로 변경하려면 올바른 개인정보처리방침 URL을 입력해야 합니다. 기본 설정으로 이동하여 올바른 URL이 맞는지 확인하세요."

    라는 팝업이 떠서 기본 설정에 들어가보니 해당 URL 창이 비어있네요
    개인정보처리방침은 어디에서 따 올 수 있는건가요?
    2018.09.10 18:56 신고
댓글쓰기 폼