본문 바로가기
코딩생초보를 위한 플러터 빠르게 한바퀴

8.firebase2-auth,storage

by 타이싸란 2023. 10. 21.

8회차 세부 과정 목차

 

 

저번 시간에 이어 firebase 기능을 다루어볼건데, 저번에는 firestore 를 했다면 이번엔 auth 와 storage 를 해볼겁니다.

먼저 auth 입니다.

1. firebase Auth 세팅

목차로돌아가기

 

이번엔 firebase의 auth 기능을 사용해볼건데요,

쉽게말해 로그인 기능을 만드려고 하는겁니다.

 

보통 로그인 방식은

 

유저가 회원가입 ->

백엔드에서 아이디와, 비밀번호를 받은뒤 데이터베이스에 저장. 단 비밀번호는 암호화하여 저장 ->

첫로그인시 아이디,비번치고 로그인 ->

백엔드에서 아이디와 , 비번을 받은뒤 비번을 암호화함 ->

데이터베이스에서 아이디를 찾음 ->

그 아이디에 연관된 암호화된 비번이 같은경우 회원정보와 JWT 어세스토큰 , 리프레시토큰 발급(토큰에 회원아이디정보가들어가있음) , 그리고 회원정보까지 같이줌 ->

클라이언트 휴대폰에 JWT 저장 ->

다음번 유저가 앱에 접속했을때 JWT로 로그인 ->

백엔드에서 JWT 해석해서 유저 ID를 뽑음 ->

데이터베이스에서 해당 ID와 같은걸 찾아서 유저에게줌 ->

유저는 자기 정보를 받고 앱에 저장 ->

유저정보가 필요할때 위에서 받은 정보를 토대로 UI로 보여줌 ->

앱에서 백엔드로 api 호출할때 header에 jwt 토큰을 넣어서 요청함 ->

백엔드에서 호출받았을때 header의 jwt를 뜯어보고 정보처리 할수있겠다 싶으면 처리함

 

이런 과정을 거칩니다.

 

firebase auth는 백엔드의 이런 과정을 대신해줍니다.

 

firebase auth 를 통해 로그인하는 방식은 auth와 firestore 기능을 합쳐서 진행이됩니다.

아이디와 비번을 쳐서 저장하는방법이 있고 여러가지 방법이 있는데 email , password 방식의 플로우만 이야기해보자면

아래와 같습니다.

 

1.1 이메일과 비밀번호를 입력하여 firebase auth를 통해 회원가입 =>

1.2 firebase auth에 해당 이메일 과 비밀번호가 등록되면서 유저유일의 랜덤코드를 생성함. uid라고함 =>

1.3 firebase auth 에서 비밀번호를 암호화하여 가지고있고 안보여줌, 개발자가 볼수있는건 id와 , 유저유일의 uid 임 =>

 

2.1 auth에 정상적으로 등록되면 등록된 해당 계정의 정보를 리턴받음. =>

2.2 그 받은 정보중에 uid를 추출함 =>

 

3.1 uid와 , 회원가입시 등록했던 각종 정보들(전화번호,이메일,이름 등등) 을 조합하여 UserDto를 만듬 =>

3.2 firestore 의 User 라는 컬렉션에 UserDto를 json 형태로 만들어서 집어넣음.(create) 집어넣을때 docId를 랜덤으로하지말고 위에서 받은 uid 로 해주면됨. 이렇게 회원가입 완료.

 

4.1 처음 로그인한다면 로그인페이지에서 email, password를 입력하여 로그인 =>

4.2 firebase auth에 해당 email과 password에 맞는 유저정보 요청

4.3 firebase auth에 해당 계정이 없으면 오류로 팅겨냄. 에러처리로 정보가없습니다 등등의 메세지를 띄어주도록하면됨  =>

4.4 해당 계정정보가 있으면 그정보를 받은뒤 그중에 uid만 추출해서 User 컬렉션에서 해당uid와 같은 docId를 가진 문서를 찾은뒤 리턴해줌. =>

4.5 그 해당문서를 예를들어 (UserVo myInfo) 라는 변수 만들어서 저장함, 그정보로 이것저것함. 

4.6 4.4에서 로그인성공했을때 유저가 스스로입력했던 email과 비번을 shared preference에 저장해둠 =>

4.6 다음번 로그인때부터는 랜딩페이지에서 shared preference에서 아이디와 비번을 찾아와서 firebase auth에 로그인. (이게 자동로그인)

 

요렇게됩니다.

그래서 한번 해보도록합시다.

 

아래 순서대로 해보겠습니다.

 

1. firebase auth 오픈

2. 플러그인 설치

3. UserVo 만들기

4. UserController만들기

5. 페이지만들기(로그인,회원가입) 

 

1. firebase auth 오픈

 

firebase 콘솔에가서 Authentication 서비스를 찾은다음 시작하기 버튼을 눌러줍니다.

 

Sign-in method탭에서 새 제공업체 추가를 누른뒤 이메일/비밀번호를 선택해주세요.

여러가지 방식들이 많죠?? 나중에 익숙해지면 전화,sns 등등 해보세요. 지금은 이메일만 합니다.

(카카오나 네이버는 없는데요?? 어나님누스라고 아래 익명 이라고있는데 이걸이용하면됩니다)

 

Users 탭에와서 사용자 추가 누른뒤 대충 이멜과 비번을 넣으면 이렇게 사용자가 추가됩니다.

뒷편에 사용자 UID가 보일건데요 이게 User 컬렉션의 문서명으로 들어갈겁니다.

콘솔에서도 생성할수있음을 보여준건데 그냥 만들어본거니 삭제해주세요. 사용자 추가 오른쪽에 점점점 세개짜리(more이모티콘) 누른뒤 계정삭제 누르시면됩니다.

 

 

 

2. 플러그인설치

우선 firebase_auth와 shared_preferences를 설치해줍니다. 

shared_preferences 는 나중에 자동로그인 구현할때 이용할라고 설치한거고, auth패키지랑은 근본적으로는 상관없어요.

 

3. UserVo 만들기

대충 이렇게 만들어봤습니다.

email과 imagePath 정도만 유저정보로 있다고 보면 되것네요.

 

4. UserController만들기

UserController 를 만들어서 myInfo 라는걸 상태관리로 만들면 되겠네요.

여기에 정보가있으면 로그인된거고, null이면 로그인 안된거라고 보면되겠습니다.

 

그리고 대략 5가지의 메소드가 있으면 될것같습니다.

 

로그인 , 오토로그인 , 내 유저정보 가져오기가 발동하면 myInfo에 정보를 담거나 재할당하고,

로그아웃 발동시 myInfo를 null로 만들면 될것같습니다. 유저등록은 그냥 발동하는 함수구요.

 

controller를 만들었으니 main쪽에 등록도 해주세요.

 

5. 페이지만들기(로그인,회원가입) 

 

페이지를 지금 꾸미진 않을꺼고 일단 그냥 빈페이지 2개를 만들어주세요.

일단 요렇게 2개만들어 놨습니다.

보통 로그인을 sign_in 이라고하고 , 회원가입을 sign_up 이라고하는데 페이지이름은 아무거나하시면 됩니다.

 

 

2. firebase Auth  유저 등록

목차로돌아가기

 

유저등록 부분은 대략 아래 순서로 하면 될것같네요.

 

1. 유저등록 함수 코딩

2. 회원가입 페이지 만들기

3. 회원가입 정보 넣고 등록해보기

 

1. 유저등록 함수 코딩

 

UserController의 addUser부터 완성시켜봅시다.

 

saranFirebaseService 에 signUpWithEmailAndPassword 라는 메소드를 만들어줄겁니다.

 

먼저 상단에 FirebaseAuth 인스턴스를 생성해주세요.

그리고 Post때처럼 User컬렉션도 만들어 줍니다.

 

signUpWithEmailAndPassword 메소드를 만들었는데요,

 

1. 먼저 FirebaseAuth. 즉 우리가 auth 로 만든 그 인스턴스에 createUserWithEmailAndPassword 라는 내장함수가 있는데 그걸 사용합니다. 매개변수로 받은 이메일과 패스워드를 넣어줍니다. 이 함수는 UserCredential 이라는걸 리턴해줍니다.

여기에는 우리가 콘솔에서 확인했었던 uid정보와 각종 정보들이 있습니다. 좀있다가 우리는 여기서 uid, email 정보만 뽑아올겁니다.

 

2. 1번이 성공하면 userCredential에서 uid 를 뽑아옵니다.

 

3. userVo 인스턴스를 만들어주는데, 여기 email 부분을 userCredential 에서 받은 email을 넣어줍니다.( 사실 매개변수로 받은 userEmail로 해도 결과는 같겠죠? 근데 본질적으로 userCrediential 에서 추출한걸로 하는게 맞는것같네요.)

 

4. 이젠 3번에서 만든 userVo 이걸 firestore에 넣어줄건데 CRUD 중에 C인 create작업에는 set 방식도 있다고 했습니다. 컬렉션.doc(문서ID) 이렇게 하면 문서아이디를 지정할수있는데 그 문서아이디를 2번에서 받은 userUid로 해줍니다.

그리고 userVo의 우리가 만들어두었던 toMap 이라는 매소드를 통해 json형태로 만들어준뒤, set(여기) 에 넣어줍니다.

 

5. 만약 에러가 났을때 처리도 해줍니다. firebaseAuth 부분에서 에러가 났을경우 , 즉 에러타입이 FirebaseAuthException 이면 그 에러의 코드를 분석해서 'email-already-in-use' 라고 되어있으면 이미 가입되어있는 이메일 입니다 라고 throw 해줍니다.

그외의 에러일 경우 그냥 error를 throw 해줍니다.

 

 

2. 회원가입 페이지 만들기

 

대충 저는 메인화면에 drawer 를 통해 여기 로그인하기 버튼하나 만든다음

로그인하기 버튼을 누르면 로그인 페이지로 넘어가도록 짰습니다.

그리고 로그인하기 아래부분에 회원가입하기 버튼을 만들어주고, 회원가입 버튼을 누르면 회원가입 페이지로 가면되겠죠.

 

 

 

지금은 가입부분이니까 로그인부분은 좀있다가 하고 , 회원가입 페이지를 꾸며줍니다.

 

 

대충 회원가입페이지는 이렇게 만들면 될것같습니다.

이메일 비빌번호등을 받고, validation 체크가 완료되서 유효하다 싶으면 그때 우리가 원하는 메소드를 실행시키면되겠죠.

사실 validation 을 쉽게하고 틀릴경우 에러메세지 띄어주고 그런 기능이 inputText 같은거에 있지만 그건 너무 지엽적인거니 일단 우리는 auth 의 본기능에 충실하고 디테일한건 나중에 스스로 해보도록하죠~

 

어쨋든 저 노란 네모부분에 우리가 원하는걸 넣으면 됩니다.

 

3. 회원가입 정보 넣고 등록해보기

 

이메일 비번 등을 입력하고, 회원가입 버튼을 누르면

각종 validation 작업에서 통과됬으면 try catch 에서 함수실행되고 성공했으면 결과가 나올것입니다.

 

잘 작동했네요.

auth 와 firestore 에 잘 등록되있는것을 확인할수 있습니다.

 

3. firebase Auth  로그인

목차로돌아가기

 

회원가입을 했으니, 해당 가입된 정보로 로그인을 해보겠습니다.

아래 순서로 하면 되겠네요.

 

1. 로그인 함수 코딩

2. 로그인 페이지 만들기

3. 로그인 여부에 따른 UI 분기

4. 자동로그인

5. 로그아웃

 

1. 로그인 함수 코딩

 

우선 userController 부분의 login 함수를 코딩해봅시다.

 

saranFirebaseService 에 signInWithemailAndPassword 라는 함수를 만들고 UserVo 형태로 리턴받을수있도록 해둔다음,

맨위에 상태관리로 만들어둔 myInfo 여기에다가 가져온정보를 넣은뒤 update 해주면 되겠네요.

 

그리고 윗작업이 에러없이 끝나면 아래쪽에 SharedPreferences 에 email과 password 정보를 집어넣어주면 될것같습니다.

 

 

firebase service 쪽에 signInWithEmailAndPassword 라는 메소드를 만들고 , 안에 내용들을 구성했습니다.

 

먼저 Firebase.instance. signInWithEmailAndPassword  라는 내장함수를 통해 , 매개변수로 받은 email과 password를 토대로 로그인을 하고 결과값으로 UserCredential 을 받습니다.

 

그 받은 정보에서 uid 를 추출한뒤,

 

firestore의 userCollerction 에서 해당 uid를 docId 로 가지고있는 문서를 찾습니다.

 

그문서를 UserVo.fromDocumentSnapShot 으로 우리가 만들어둔 매소드를 통해 인스턴스화 시킨뒤 리턴해줍니다.

 

 

2. 로그인 페이지 만들기

 

아까 로그인 페이지 만들었던거에서 버튼부분에 로직들만 넣어서 적절하게 해줍니다.

 

로그인을 눌렀더니 로그인 잘됩니다. 근데 로그인 잘됫는지 확인을 못하고있네요.

 

3. 로그인 여부에 따른 UI 분기

내가 로그인이 잘되서 정보가 잘들어왔는지 눈으로 확인이 안되니

로그인 됬으면 로그인하기 대신 내 정보보기 버튼으로 바뀌면 될것같습니다.

메인페이지의 scaffold 옵션에 drawer 정보가 있는데, 이걸 GetBuilder 로 감싸준뒤 controller2 로해줍니다.

(그이유는 해당 페이지의 Scaffold 를 이미 다른 GetBuilder 로 감쌌고 PostController를 받아서 controller 로 해줬으니까요)

 

어쨋든 요렇게 로그인 안되어있을때, 즉 myInfo가 null 일때는 로그인하기가 보이게 해두었고,

로그인이 됬다면 즉 myInfo에 정보가있을때는 내정보의 이메일을 불러오고 버튼명이 마이페이지로 되게 해뒀습니다.

 

4. 자동로그인

 

한번 이메일 과 비밀번호를 쳤으니, 앱을끄고 다시 들어왔을때, 또 계정정보 넣고 로그인하면 귀찮으니

자동로그인을 넣어봐야겠습니다.

 

먼저 컨트롤러부분에서 함수를 코딩해줍시다.

윗부분 login에서 로그인이 됬으면 prefs.setString 을 통해 email , password정보를 저장했을겁니다.

 

그래서 autoLogin 부분에서는 prefs 에서 getString 을 통해 저장되어있던 email과 password를 불러오는데요

만약 정보가 없으면 return 으로 그냥 함수를 종료시켜버립니다.

정보가있다면 아래 부분으로 계속 코딩을 읽어나갈텐데

try부분에 그냥 위에 만들어두었던 login 함수를 그대로 사용하면되겠네요.

 

그리고 만약 실패했을때 prefs 에서 email 과 password 를 삭제해주도록 했습니다.

 

그뒤 main 함수에서 runApp이 실행되기전에 오토로그인을 해주면 되겠네요.

 

사실 runApp 이후에 MaterialApp의 home부분에 MainPage로 바로가는게 아니라, SplashPage 같은걸 만들어서 거기에서 오토로그인 해주는게 맞습니다.

runApp -> SplashPage(앱초기 MainPage에서 필요한 것들을 다운받거나설정) -> MainPage 이런 플로우죠.

어쨋든 저 위에 넣어둔거는, 앱의 초기부분에서 오토로그인을 시도한다는 점이 본질입니다.

 

그럼이제 앱껏다 실행하면 자동적으로 로그인 되어있을겁니다.

 

5. 로그아웃

 

대충 로그아웃 버튼도 만들었습니다.

유저정보가 있을때만 나타나도록 해둔 버튼이죠.

 

컨트롤러 부분에 logout 함수부분을 코딩했습니다.

 

firebaseService의 signOut 함수를 만들고 그거 먼저 실행시켜준뒤,

(signOut 부분은 그냥 auth.signOut 하면 firebase auth의 정보가 다 날아갑니다.)

그냥 myInfo를 null로 바꾸고 update 시켰습니다.

 

그리고 prefs 에 email 과 password 정보를 날려줍니다.

그러면 다음에 앱을켯을때 자동로그인이 되지 않겠죠. 로그아웃을 한번했으니 자동로그인도 포기한다고 생각하고 저렇게해둔겁니다.

 

그리고 참고로 SharedPrefereces 저 인스턴스 만드는 부분에 노란박스를 친 이유는, 앞에 함수에서부터 계속 저걸 정의하고 사용하고있는데 저건 앱에서 한번만 생성해줘도 됩니다. 싱글톤 형태의 인스턴스라서 그냥 글로벌변수에 하나 생성해두고 사용하면되는데, 지금 이해하기가 힘들수있으니 걍 할때마다 저렇게 중복으로 작성하고있는데, 사실한번만하면됩니다.

 

로그아웃이 다되면 심심풀이로 그냥 GetX 라이브러리 기능중에 하나인 snacbar 를 띄어주게 해줬습니다.

 

로그아웃 버튼누르니까, 아래 스낵바 뜨고, 위에는 로그인 안했을때의 ui  가 나오는걸 볼수있습니다.

로그아웃 처리가 잘되었네요.

 

여기까지했으면 auth 의 기본적인건 다했고, 나머지는 검색으로 알아낼수있을 정도가되었습니다.

 

4. firebase storage 세팅

목차로돌아가기

 

파이어베이스 스토리지 (이하 스토리지) 는 하나의 파일서버입니다.

이미지나 , 텍스트 파일 등등 잡다한 파일들을 올려두고 주소를 통해 파일을 다운받거나 뭐하거나 하는거에요.

AWS 의 S3 스토리지와 같은 개념으로 보면됩니다.

실습에서는 여기에 이미지 파일만 올려두고 사용할겁니다.

 

콘솔에서 빌드쪽부분을 눌러보시면 Storage가 나옵니다. 시작하기를 눌러주세요.

 

그냥 프로덕션 모드에서 시작하신뒤, 리젼 고르는곳있는데 여긴 firestore리전과 같은걸로 됩니다. 완료를 눌러서 생성해주세요.

약 30초 정도 뒤에 스토리지가 만들어지는데, firestore할때랑 마찬가지로 Rules들어와서 if false 지워주세요.

Files 에 와보면 대충이렇게 나옵니다.

콘솔에서 폴더생성할수있고, 파일 업로드 할수도 있고 , 그렇습니다.

 

pubspec에 firebase_storage 설치도 해주세요.

 

이렇게 기본세팅이 끝났습니다.

 

5. firebase storage 이미지 올려보기.

목차로돌아가기

 

실습과정은 이렇습니다.

 

1.마이페이지 만들기 ->

2.내 정보 다시 가져오기 메소드 만들기 ->

3.내 이미지 변경하기 메소드 만들기 ->

4.내 겔러리에서 사진 불러오기(Image Picker) ->

 

그럼 한번 진행해봅시다.

 

1.마이페이지 만들기

 

 

대충 드로월에서 마이페이지로 들어가는 걸 만들어줬습니다.

 

마이페이지 부부네 이미지 들어갈곳을 만들어줍니다.

그냥 Image.network 를 사용해서 myInfo의 imagepath 불러오고 , 에러나면 대충 아이콘 나오게 해줬습니다.

 

그리고 사진올리기라는 버튼을 누르면 사진고른뒤 업로드 하는 과정을 거치면 될것입니다.

 

 

2.내 정보 다시 가져오기 메소드 만들기->

 

 

컨트롤러에 내정보다시불러오기랑 , 이미지 변경하기 메소드를 만들건데

먼저 내정보 다시 불러오기를 만들어봅니다.

 

myInfo의 정보가없으면 그냥 return을 통해 함수를 종료해 버리구요,

아니면 Service 부분에 getMyInfo라는 함수 만든다음, 매개변수로  docId 주고 UserVo를 리턴받도록 코딩해줍니다.

그 결과로 UserVo 를 받으면 myInfo에 덮어쓴뒤 update처리해주면 되겠네요.

 

3.내 이미지 변경하기 메소드 만들기 ->

 

컨트롤러에 이미지 변경하는 메소드도 만들어줍니다.

service에 editImage라는 메소드를 만든다음 매개변수로 docId , image파일을 준뒤, 완료되면

위에만들어둔 getMyInfo를 불러서 내 정보를 갱신해주도록 했습니다.

여기서 File image 부분에 File 이거는 flutter에 기본으로 깔려있는 라이브러리를 사용하는데 io 라는 패키지입니다.

 

service부분의 editImage메소드를 설명해보면,

우선 FirebaseStorage.instance로 위에 생성해주시고요.

 

1.먼저 파일이 스토리지에 어떤 폴더에 들어갈것인지 경로를 설정해줍니다.

제가 해둔거든 profileImageUrl 이라는 폴더에 sdfsefsfsdfsd.png 뭐 이런식으로 들어가게 될겁니다.

 

2.putFile 이라는 메소드를 통해 실제로 파일을 스토리지에 올립니다.

 

3. 스토리지에 다올라갔으면 그 주소를 받습니다.

 

4. 받은 주소를 firestore에 등록되있는 내 유저정보의 imagePath라는곳에 적습니다.(crud 중에 update겠죠?)

 

그럼이제 메소드 부분은 완성이 됬습니다.

 

 

4.내 겔러리에서 사진 불러오기(Image Picker) 

 

 

이미지 피커 설치 ->

더보기

우선 pub에가서 Image Picker 라는걸 검색해서 설치해줍니다.

 

이렇게 pub에 등록하는과정은 이제 생략해도 되겠네요.

 

이미지 피커를 쓸려면 몇가지 설정을 해줘야합니다.

원래는 안드로이드도 설정을 해줬어야했는데, 패키지가 업데이트 되면서 안해도 되나봅니다.

 

IOS는 좀 해줘야하는데요 Info.plist 찾아가서 아래부분에 저거를 적어줍니다.

<key>NSCameraUsageDescription</key>
   <string>프로필 사진 등 사진 업로드에 사용됩니다.</string>
   <key>NSMicrophoneUsageDescription</key>
   <string>프로필 사진 등 사진 업로드에 사용됩니다.</string>
   <key>NSPhotoLibraryUsageDescription</key>
   <string>프로필 사진 등 사진 업로드에 사용됩니다.</string>

 

 

아까 만든 마이페이지 에서 사진올리기 라는 버튼을누르면 무슨 작동이 되어야하는데

여기에 들어갈 내용은 이렇습니다.

 

저 버튼을 누르면

1.Image Picker라는 라이브러리의 pickImage 라는 메소드를 이용해서 그중에 gallery에서 가져온다고 해둡니다.

겔러리가 나타나면 사진한장을 고릅니다.

 

2.Image Picker는 리턴하는 파일형태가 XFile이라는 형태로와서 이걸 File로 바꿔줍니다.

 

3.컨트롤러의 이미지변경메소드를 호출할때 이미지 파일을 매개변수로 줍니다.

 

사진올리기 버튼을 눌렀더니 이렇게 겔러리가 나타납니다.

여기서 그냥있는 사진하나 선택했더니 저렇게 이미지가 바뀌는게 보입니다.

그럼 성공이죠.

이미지가 왜 사각형이냐? 

컨테이너는 원형으로 만들었는데, 그안에 Image 위젯으로 받은건 영향이 없어보이네요.

이건 그냥 Image 위젯을 ClipRRect로 감싼뒤 borderRadius 주면됩니다.

 

어쨋든 이렇게 이미지가 바뀐것을 볼수있습니다.

 

 

이렇게 스토리지에 파일올리기도 해보았습니다.

 

여기까지 하면 기본적으로 앱을 구성하고, 자신이 원하는 앱을 만들수있는 여건이 만들어졌습니다.

디자인이나 좀더 세밀한 부분(이메일이나 비번입력할때 validation) 등등 지엽적인건 챗GPT ,블로그 , flutter공식 문서를보며 해보면됩니다. 그래서 다음강의에서는 배포과정을 할건데요, 배포과정에 들어가기전 자신이 원하는 앱을 한번 만들어보시기 바랍니다.

그걸 배포할거에요.

 

 

'코딩생초보를 위한 플러터 빠르게 한바퀴' 카테고리의 다른 글

0.OT and Install  (0) 2023.11.04
9.distribution  (0) 2023.10.27
7.firebase1-firestore  (0) 2023.09.02
6.network  (0) 2023.08.22
5.state management  (0) 2023.08.11