Don't think! Just do it!

종합 IT 기술 정체성 카오스 블로그! 이... 이곳은 어디지?

Flutter/Flutter Study

[Flutter] Firebase auth email link login

방피터 2022. 10. 21. 18:28

Firebase auth에서 email password 로그인 말고 email link 로 로그인하는게 있어.
그냥 email, password하면 되지 왜 사서 고생이냐고? firebase 방식이 email이랑 password만 입력하면 바로 계정을 만들 수 있어. email을 소유자 확인없이 말이지!
물론 email verification을 하면 돼. 기능도 있고. 내가 등신인지 모르겠다만..자! 생각을 해보자. 그림 보면 심플! 👇

이멜 + 비번 방식에서 이멜 verification

그런데 말이지! 만약 악의적인 사용자가 훔친 이멜 주소로 회원 가입을 시도해. 앱은 verification을 보내고 기다릴텐데 그 동안 이멜 진짜 주인이 가입을 시도한다 치자! 그럼 어떻게 돼? 실제 이멜 주인은 10분을 기다렸다가 다시 가입하던지, 아니면 비번 찾기를 누르거나, 아니면 찝찝해서 앱을 지우겠지. 뭐 설마 10분만에 이런 일이 일어나겠어?할수도 있는데.. 세상에는 생각보다 미친놈들이 많아 ㅋㅋ

세상은 넓고 미친놈은 많다.

그 뿐만이 아니라 백엔드에서 10분을 기다렸다가 계정을 삭제하는 코드를 돌리기도 해야하고... 괜한 낭비 아닌가?
내가 잘못 알고 있는 거면 좀 알려주고(제발!)

이멜로 Signin 링크 전송

그래서 아예 비번이 없는 시스템으로 가자 해서 시도해 본 게 firebase auth email 링크로 로그인이야. 비번을 입력할 필요가 저언혀 없지! 백앤드에서 10분을 기다렸다가 계정을 삭제하는 짓거리는 할 필요가 없어. 그래서 시도해봤지. 👇
https://firebase.google.com/docs/auth/flutter/email-link-auth

이메일 링크를 사용하여 Firebase로 인증  |  Firebase 문서

Google I/O 2022에서 Firebase의 새로운 기능을 확인하세요. 자세히 알아보기 이 페이지는 Cloud Translation API를 통해 번역되었습니다. Switch to English 의견 보내기 이메일 링크를 사용하여 Firebase로 인증 컬

firebase.google.com

그런데 이게 순서대로 쫘악 나와 있는 문서가 없더라고 ㅠㅠ 그래서 엄청 고생함! 개짜증! 니들은 고생하지 말라고~ 자 시작해보자.

일단 처음은 앱에서 유저 이메일을 보내는 작업부터야. 아래처럼 Action code를 설정하고 이메일과 함께 보내면 유저 이메일로 SignIn link가 전달돼.

Future<void> sendCreateAccountLink(String email) async {
    var acs = ActionCodeSettings(
        url: "파이어 베이스 다이나믹 링크!",
        handleCodeInApp: true,
        iOSBundleId: 'ios 번들 id',
        androidPackageName: 'android 패키지 id',
        androidInstallApp: true,
        androidMinimumVersion: '12');
    userEmail.value = email;
    try {
      return await auth.sendSignInLinkToEmail(
          email: email, actionCodeSettings: acs);
    } catch (e) {
      rethrow;
    }
  }


이 때 url은 firebase에서 설정한 동적 링크 주소를 넣어야 하니까 firebase 콘솔로 고고!

파베 동적링크

시작하기 눌러주시고~

니들이 원하는 도메인 이름 입력해주시고~
그러면 생성이 되는데 대소문자 의미 없는거 알지?
동적 링크 도메인이 설정되었음.

이제 새 동적 링크를 만들자. 단축 링크부터 설정하는데 이쁜 이름으로 넣자~ 막하지 말고 ㅋㅋㅋ

URL 뒤에 이쁘게 넣자. Eit5 이딴 거 말고 ㅎ

그 다음에는 동적링크를 설정인데 여기에 딥링크에 사용할 URL을 넣을겨.. 그런데 이건 email verification에서 사용할 URL을 넣어야 하는데 "https://파이어베이스프로젝트이름.firebaseapp.com" 이렇게 넣어줘야 함. 동적 링크 이름은 아무거나 하자.

이거 때문에 뻘짓 5시간 했음.

이제 링크 동작 정의. 이건 브라우저에서 딥 링크 URL 열기, Apple 앱에서 딥 링크 열기 둘다 해봤는데 email signin은 둘다 되더라고;;

링크 동작 설정.

그런데 Apple에서 딥 링크 열기를 선택하면 App Store ID하고 팀ID 입력해줘야해~(1년 100불짜리 개발자 맴버쉽 있어야 함!) 더 자세한 건 동적 링크 다른 기능을 사용해보면서 차차 알아가면 될 듯하니까 패스. 안드로이드 링크 동작도 똑같이 정의해주고 선택 사항은 패스. 그리고 만들자.

동적 링크가 만들어졌다.

이제 여기에 있는 URL을 복사해서 sendCreateAccountLink()에 사용하도록 하자.

Future<void> sendCreateAccountLink(String email) async {
    var acs = ActionCodeSettings(
        url: "https//domainwhatyouwan.page.link/ib87",//여기에~!!!!!
        handleCodeInApp: true,
        iOSBundleId: 'ios 번들 id',
        androidPackageName: 'android 패키지 id',
        androidInstallApp: true,
        androidMinimumVersion: '12');
    userEmail.value = email;
    try {
      return await auth.sendSignInLinkToEmail(
          email: email, actionCodeSettings: acs);
    } catch (e) {
      rethrow;
    }
  }

이제 앱이 설치된 휴대폰에서 메일로 전달된 링크를 열면 앱이 실행되면서 동적 링크가 전달될거야. 전달된 동적 링크를 처리해보자규. 동적 링크 패키지 설치 고고~

%flutter pub add firebase_dynamic_links

그리고 나는 Getx로 하고 있어서 동적 링크 부분을 GetxController로 만들었어 👇 원래는 local storage에 email도 저장하고 해야 하지만 지금은 걍 공부하면서 하는 거니까 흐름만 보라구 흐름만 ㅋㅋ

import 'package:get/get.dart';
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
import 'package:exampleApp/controllers/authController.dart';

FirebaseDynamicLinks dynamicLinks = FirebaseDynamicLinks.instance;

class DynamicLinkController extends GetxController {
  static DynamicLinkController get to => Get.find();
  late Rx<PendingDynamicLinkData?> initLink;
  late Rx<PendingDynamicLinkData?> deepLink;

  @override
  void onInit() async {
    // TODO: implement onInit
    // initLink = Rx<PendingDynamicLinkData?>(await dynamicLinks.getInitialLink());
    deepLink = Rx<PendingDynamicLinkData?>(await dynamicLinks.getInitialLink());
    deepLink.bindStream(dynamicLinks.onLink);
    super.onInit();

    ever(deepLink, (_) {
      //signin link가 맞는지 검사
      if (auth.isSignInWithEmailLink(deepLink.value!.link.toString().trim())) {
        //link와 사용자 email로 SignIn
        auth.signInWithEmailLink(
            email: AuthController.to.userEmail.value,
            emailLink: deepLink.value!.link.toString().trim());
      } else {
        print("Something wrong!!");
      }
    });
  }
}

dynamicLinks.onLink가 stream이라 deepLink 변수 하나 만들어서 바인드 해주고 ever로 deepLink가 변경될 때마다 callback이 수행되도록 해놨어. callback에서는 link가 정상인지 확인하고 Signin 하는 거지. 그런데 이게 끝이 아냐 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
안드로이드는 아직 안해봐서 모르겠고 Ios에서는 할게 더 남았어 ㅋㅋㅋ xcode로 가자! ㅋㅋ

xcode 딥링크 설정.

Capability에서 Associated domains를 추가. 도메인에 applinks:domainwhatyouwant.page.link 형식으로 입력. 그리고 한가지 더 Info탭으로 이동해서 URL types를 추가해줘야 해.

딥링크 xcode 설정

identifier는 아무거나 입력하고 URL Schemes에는 동적링크 프리픽스만 입력해주면 돼. "domainwhatyouwant.page.link" 이런식으로 말이야. 그리고 나서 테스트해보면!👇

firebase 이메일 signin 딥링크 테스트

비번 같은 건 신경쓰지 말자. 전부 빼버릴거임 ㅋㅋㅋ 이메일 링크가 스팸으로 빠지는 것도 신경쓰지 말자 ㅋㅋ 암튼 잘 동작하는 건 확인했으니 다행이긴 하다~ 이제 집에 갈 시간이 다 되서 휘갈긴다 ㅠㅠ 우리 아들 보러 가야해~
궁금한 거 있으면 댓글달어~ 앙녕~

반응형