[Flutter] Firebase Auth-1

한상욱·2023년 5월 28일
0

Flutter with Firebase

목록 보기
9/10
post-thumbnail
post-custom-banner

들어가며

이번 포스팅에서는 Firebase의 Authentification을 이용해서 로그인 기능을 간편하게 구현하는 방법에 대해서 알아보겠습니다.

Firebase Authentification

대부분의 어플리케이션은 인증수단이 필요합니다. Firebase Authentification은 Firebase와 연동되어 있는 프로젝트에게 간단하고 다양한 인증서비스를 제공합니다. 예를들어, 다른 인증서비스를 제공하는 Google, Apple, Facebook 등 여러가지 인증 서비스를 엮을 수도 있고, 이메일 인증이라던지, 전화번호 인증같은 기능을 제공해줘요. 그리고 보안규칙과 Firebase Authentification을 함께 엮어서 보안을 강화할 수도 있습니다. 그러면 이제 시작해볼까요?

Login UI

저희가 이번 포스팅에서 사용할 UI입니다.

간단하게 이 로그인 UI의 동작을 설명드리겠습니다.

미리 만들어놓은 UI입니다. 로그인 버튼을 클릭하면 인증시간 동안 로딩위젯을 보여줍니다.

인증이 완료되면, 인증이 완료되었다는 이미지를 보여주고, 다음 화면으로 넘어갑니다 !

UI에 대해서 간단하게 알아보았으니, 이제 진짜 인증 기능을 구현해봅시다 !

Firebase Authentification 시작하기

기본적으로 파이어베이스 연동이 되어있어야 합니다. 연동하는 방법에 대해서는 지난 포스팅을 확인해주세요.

파이어베이스 연동하기

이제, 콘솔에서 auth기능에서 필요한 것들을 활성화하겠습니다.

시작하기를 눌러줍니다.

이제, 이 곳에서 이메일/비밀번호 방식을 허용하여, 첫 로그인 방법을 추가해야 합니다. 만약 이메일/비밀번호를 사용하지 않을거다. 하면, 흠...직접 만들어야 되려나..? 잘 모르겠습니다.

아무튼, 이메일 비밀번호 방식을 허용합시다.

이젠 기본적인 인증 기능을 사용할 수 있습니다. 콘솔에서 설정이 끝났다면, 적용하고자 하는 Flutter 프로젝트에서 firebase_auth 패키지를 install합니다.

패키지 install하기 위해서 터미널에서 아래 명령어를 입력합니다.


자, 이제 Auth 기능을 사용할 수 있습니다 !

회원가입과 로그인, 로그아웃

이번 포스팅에서는 아래와 같이 회원가입 후, 로그인과 로그아웃하는 방법을 보여드릴겁니다.

사용자 등록

로그인을 하기 위해서는 먼저 사용자 등록과정을 거쳐야 합니다. 사용자 등록 페이지의 UI는 로그인 UI와 비슷해요.

예제를 위해서 비밀번호 확인과 같은 Validation 기능은 생략할게요. 이제 사용자 등록을 위한 함수를 만들어봅시다.

  void signUp() {
    setState(() {
      isLoading = true; //애니메이션 효과를 위한 변수
    });
    try {
      FirebaseAuth.instance
          .createUserWithEmailAndPassword(
              email: email.value.text.trim(),
              password: password.value.text.trim())
          .then((value) {
        setState(() {
          isLoading = false;
          showResisterDialog();
        });
      });
    } on FirebaseAuthException catch (e) {
      if (e.code == 'weak-password') {
        print('The password provided is too weak.');
      } else if (e.code == 'email-already-in-use') {
        print('The account already exists for that email.');
      }
    } catch (e) {
      debugPrint('에러');
    }
  }

코드를 간단하게 설명하자면, 이메일과 비밀번호를 TextEiditingController를 이용해서 입력받습니다. 그리고 버튼을 클릭하면, isLoading을 통해서 로딩위젯을 랜더링하고, 사용자 등록이 완료되면, Dialog를 보여줄겁니다. 그러면 Dialog를 보여주는 함수는 어떻게 되어있는지 볼까요?

  void showResisterDialog() {
    showDialog(
        context: context,
        builder: (context) => AlertDialog(
              title: const Text('환영합니다 !'),
              content: const Text('회원가입을 완료했습니다 ! 확인 버튼을 클릭하면 로그인 화면으로 이동합니다.'),
              actions: [
                TextButton(
                    onPressed: () {
                      FirebaseAuth.instance.signOut();
                      Navigator.of(context).pushAndRemoveUntil(
                        MaterialPageRoute(
                          builder: (_) => const Root(),
                        ),
                        (route) => false,
                      );
                    },
                    child: const Text('확인'))
              ],
            ));
  }

확인을 클릭하면 로그인 화면으로 이동해서 바로 로그인을 할 수 있습니다. 여기서는 이 다음과정에서 StreamBuilder를 사용하기 때문에 signOut을 통해서 로그아웃하고, Root로 이동해야 합니다.

인증/비인증 화면 제어

로그인과 로그아웃은 StreamBuilder를 통해 인증이 되었다면 메인화면을, 그렇지 않다면 로그인화면을 보여주겠습니다. 이를 위해서 root.dart파일을 만들어서 MaterialApp의 home으로 전달하겠습니다. 아래는 root.dart의 내용입니다. import는 생략했습니다.

class Root extends StatelessWidget {
  const Root({super.key});

  
  Widget build(BuildContext context) {
    return StreamBuilder(
        stream: FirebaseAuth.instance.authStateChanges(),
        builder: (context, snapshot) {
          if (!snapshot.hasData) {
            return const Login();
          } else {
            return const Home();
          }
        });
  }
}

MaterialApp의 home에 Root를 전달해야겠죠?

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
          backgroundColor: Colors.white, focusColor: Colors.blueAccent),
      home: const Root(),
    );
  }
}

authStateChanges()메소드를 이용해서 현재 사용자가 인증이 되었는지, 안되었는지 확인할 수 있습니다. 데이터가 없다면 로그인화면으로 자동으로 이동하겠죠?

로그인

이제 로그인을 위해서 signIn()메소드를 만들겠습니다. 우선, TextField의 값이 비었는지 확인하기 위해 validation을 하겠습니다.

  void validate() {
    if (email.value.text.trim() == '' || password.value.text.trim() == '') {
      return; //값이 비었다면, 아무것도 수행하지 않음.
    }

    setState(() {
      isLoading = true; // 로딩 애니메이션을 위한 불리언 변수 활성화
    });

    Future.delayed(const Duration(seconds: 2)).then((value) {
      setState(() {
        isLoading = false; //로딩 종료 그리고 signIn()실행.
        signIn();
      });
    });
  }

TextField의 값이 비지 않았다면, 로딩 애니메이션을 보여줄겁니다. 그리고 나서, signIn()메소드를 실행합니다.

void signIn() {
    try {
      showCheck();
      FirebaseAuth.instance
          .signInWithEmailAndPassword(
              email: email.value.text.trim(),
              password: password.value.text.trim())
          .then((value) => Navigator.of(context).pop());
    } catch (e) {
      debugPrint('에러');
    }
  }

이후, 인증에 그 어떠한 에러도 없다면, 인증을 완료한 후, showCheck Dialog를 종료합니다. 아래는 showCheck()메소드입니다.

  void showCheck() {
    showDialog(
        context: context,
        barrierColor: Colors.black26,
        builder: (context) => Center(
              child: _accept(),
            ));
  }

단순히, 애니메이션을 위한 asset들이 들어가 있습니다. 한번 로그인이 잘 되는지 확인해볼까요?

로그아웃

드디어 로그아웃입니다. 로그아웃은 굉장히 간단합니다.

  void signOut() {
    FirebaseAuth.instance.signOut(); //로그아웃
  }

다음 메소드를 이용해서 로그아웃을 할 수 있습니다.

마치며

이번에는 Firebase Authentificaion을 이용한 간단한 회원가입, 로그인, 로그아웃을 구현해봤습니다. 다음 포스팅에서는 더 다양한 Auth기능을 소개하겠습니다 !

프로젝트 소스코드

profile
자기주도적, 지속 성장하는 모바일앱 개발자가 되기 위해
post-custom-banner

0개의 댓글