[firebase] updatePassword 에러 처리 (reauthenticateWithCredential() 적용방법)

데구르르·2024년 2월 6일
0

Flutter

목록 보기
16/17
post-thumbnail

문제상황

프로젝트에서 비밀번호 변경 페이지를 맡아 개발하고 있었다. firebase를 사용해 이메일/비밀번호로 인증관리를 했는데, firebase에서는 보안상의 이유로 직접 유저의 비밀번호를 가져올 수 없기 때문에 updatePassword()로 비밀번호를 바꿔주었다.

FirebaseAuth.instance.currentUser
                        ?.updatePassword(_newPasswordController.text);

TextField에 입력한 값을 메소드에 전달하면 끝인 줄 알았다. 하지만 변경이 될 때도 있고 안될 때도 있었다. 그리고 콘솔에는 아래와 같은 에러 메세지가 떴다 😭😭😭

해결

updatePassword의 설명은 위와 같다. 읽다보면 중요한 부분이 있는데, 이 함수는 보안의 이유로 재인증을 먼저 해줘야 한다. 즉, reauthenticateWithCredential()을 사용해서 재인증을 한 후 비밀번호를 변경해야 하는 것이다.

  1. 현재 credential 저장

현재 비밀번호를 입력하는 TextField를 만들어 유저로부터 현재 비밀번호를 입력받았다. 이 입력값을 credential의 password 필드에 넣어주었다.

 final cred = await EmailAuthProvider.credential(
                          email: currentUser.email!,
                          password: _currentPasswordController.text);
  1. reauthenticateWithCredential 함수 호출

currentUser에 reauthenticateWithCredential()을 호출한다. 인자로는 위에서 저장해둔 credential을 사용한다.

final currentUser = FirebaseAuth.instance.currentUser!;

currentUser.reauthenticateWithCredential(cred);
  1. then() 안에 updatePassword() 호출

재인증이 끝난 후 비밀번호를 변경하기 위해 then() 안에서 updatePassword()를 호출한다.

currentUser.reauthenticateWithCredential(cred)
	.then((value) async {
   		await currentUser
              .updatePassword(_newPasswordController.text);
              // 비밀번호 변경 후 해야하는 작업 추가
              // ex. 로그아웃, 로그인 페이지 이동

          
    })
  1. reauthenticateWithCredential() 에러 처리

reauthenticateWithCredential()에 대한 설명인데, 무려 예외 케이스가 7개나 있다 😭 내 코드에서는 유저가 입력한 현재 비밀번호가 실제 비밀번호와 다른 경우 invalid-credential 에러가 발생했다. 그래서 catchError()로 예외 처리를 했다.

아래는 예외처리까지 적용한 코드이다.


currentUser.reauthenticateWithCredential(cred)
	.then((value) async {
   		await currentUser
              .updatePassword(_newPasswordController.text);
    }).catchError((error) {
        if (error is FirebaseAuthException) {
          if (error.code == 'invalid-credential') {
              ScaffoldMessenger.of(context).showSnackBar(
                  const SnackBar(
                     content: Text('입력하신 현재 비밀번호가 틀렸습니다.'),
                  ),
          	);
       	} 
        // 다른 예외 경우에 대한 처리 추가하면 좋음
        else {
           ScaffoldMessenger.of(context).showSnackBar(
              const SnackBar(
                  content: Text('인증 오류가 발생했습니다. 잠시후 다시 시도해주세요.'),
                 	),
              );
        	}
 	} 
    // FirebaseAuth와 관련되지 않은 예외 처리
    else {
 		ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
                content: Text('오류가 발생했습니다. 잠시후 다시 시도해주세요.'),
                ),
           	);
         }
});

FirebaseAuthException인 경우와 그 외의 예외를 구분했고, FirebaseAuthException 중에서 특정 케이스 (나의 경우 invalid-credential)에 대한 예외 처리를 할 수 있도록 구현해봤다.

소감

역시 인증 관련 로직 구현은 복잡하다. firebase로 간단하게 했음에도 신경써야할게 많다는걸 알게 되었다. firebase에서도 나름 보안을 신경쓴 것 같아 안심이다!

profile
개발 기록

0개의 댓글