티스토리 뷰

728x90

 

문자가 오면 인증번호를 자동으로 읽어와서 input field에 입력해주기

앱 서비스 이용하다 보면 인증번호 입력하는 부분이 자동으로 입력 처리되는 서비스들을 많이 경험해보셨을겁니다. 
그 기능은 sms autofill 이라고 많이 불립니다. 

sms autofill 구현 과정을 자세히 적어보았습니다. 

 

먼저, 관련한 키워드 들을 먼저 살펴볼게요! 

- Apple Keyboard QuickType
: apple 소프트웨어 키보드로, SMS로 전달받은 인증번호를 자동으로 캐치해주고 상단에 붙여넣기를 할 수 있도록 OS 단에서 자동으로 기능을 제공해준다. 

- AppSignature
: Android 앱 서명값으로 Android 에서 특정 앱을 위한 문자인지 확인하기 위한 수단으로 활용된다.

 


iOS Solution

일단, ios 에서는 문자의 내용을 읽어올 수 있는 기능을 구현할 수 없습니다. 
다만 QuickType 이라는 기능을 이용해서 자체적으로 인증번호를 붙여넣기를 할 수 있도록 시스템을 활용할 수 있습니다.

키보드 위에 인증번호 1234을 바로 붙여넣기 할 수 있음

apple developer 사이트에는 권장하는 가이드라인이 존재하니 참고해도 됩니다.

권장하는 가이드라인
- iOS 12 이상부터 지원 
- 메시지 형식은 단순해야하며, 코드가 메시지의 마지막 부분에 있어야 함 

Your Example code is 123456.

 

하지만, 저는 아래처럼 작업을 해보았습니다. 다행히 잘 인식합니다. 

[내 서비스 인증번호 발급]
내 서비스에 가입해 주셔서 감사합니다.
회원님의 고유 인증번호가 발급되었습니다.
> 인증번호 : 12345678

 


Android Solution

Android는 문자 메시지의 내용을 읽어올 수 있습니다. 
단, 모든 앱에서 문자 메시지 정보를 읽어오면 보안에 문제가 생기니, AppSignature 값이 매칭된 메시지만 읽어올 수 있습니다. 

사용한 flutter 라이브러리는 sms_autofill 입니다. 
https://pub.dev/packages/sms_autofill

 

sms_autofill | Flutter package

Flutter plugin to provide SMS code autofill support

pub.dev

 

문자메시지 가이드라인은 다음과 같습니다. 

1. 시작에는 # 문자가 있어야 한다. 
2. 마지막 문자엔 AppSignature 값을 넣는다. 

<#> [내 서비스 인증번호 발급]
내 서비스에 가입해 주셔서 감사합니다.
회원님의 고유 인증번호가 발급되었습니다.
> 인증번호 : 12345678
KdQ911xYz


위에 문자의 마지막 텍스트인 KdQ911xYz 가 AppSignature 라고 보면 됩니다. (임의의 숫자를 넣었고 진짜 AppSignature 는 아닙니다😆)

문자 메시지에 시작시 #을 추가하고, 마지막에 AppSignature 값인 KdQ911xYz 를 포함하도록 문자메시지 기능을 구현하는 백엔드 팀에게 공유해줘야겠죠?

해줄거지?

 

Q) AppSignature 값은 어떻게 알아내나요? 

A) SmsAutoFill().getAppSignature 함수를 이용하면 됩니다. 

() async {
  final signature = await SmsAutoFill().getAppSignature;
  talker.log("appSignature: $signature");
}();

 

자, 그럼 이제 인증번호를 읽어내는 로직 작업을 해 봅시다. 

언제 인증 문자가 들어올지 모르니 listener 등록을 하고 update 리스너에서 데이터를 읽어와야 합니다. 

위의 기능을 담당하는 SmsCodeHandler를 만들어봤습니다. 

import 'package:mora_care/utils/extensions/ObjectExtensions.dart';
import 'package:sms_autofill/sms_autofill.dart';

import '../main.dart';

class SmsCodeHandler with CodeAutoFill {
  final Function(String) onCodeReceived;

  SmsCodeHandler(this.onCodeReceived);

  String _getRegex(int codeLength) => '\\b\\d{$codeLength}\\b';

  @override
  void codeUpdated() {
    talker.log("codeUpdated code: $code");
    code?.let((_code) => onCodeReceived(_code));
  }

  void startListening({required int codeLength}) {
    listenForCode(smsCodeRegexPattern: _getRegex(codeLength));
  }

  void stopListening() {
    cancel();
  }
}

 

sms_autofill 라이브러리에서 제공해주는 함수인 listenForCode를 이용해서 리스너 등록을 시작하면 됩니다. 

파라미터로 smsCodeRegexPattern 이라는 정규식을 넣을 수 있는데, 원하는 정규식을 뽑아올 수 있습니다. 

파라미터를 넣지 않으면 기본적으로는 6자리 숫자 를 뽑아옵니다. 

예를들어 숫자 10자리 인증번호를 사용하는 서비스라면 정규식으로 10자리 숫자를 받아오도록 정규식을 입력할 수 있도록 Handler를 만들어 놓았습니다. 

그리고 codeUpdate 함수를 상속받아서 원하는 조건의 인증번호를 받으면 됩니다! 

@RoutePage()
class LoginScreen extends HookConsumerWidget {
  LoginScreen({super.key});

  final TextEditingController codeController = TextEditingController();
  
@override
Widget build(BuildContext context, WidgetRef ref) {
  () async {
    final signature = await SmsAutoFill().getAppSignature;
    talker.log("appSignature: $signature");
  }();

  if (Platform.isAndroid) {
    final handler = useMemoized(() => SmsCodeHandler((code) {
          codeController.text = code;
        }));

    useEffect(() {
      handler.startListening(codeLength: 10);

      return () {
        handler.stopListening();
      };
    }, [handler]);
  }
  
  
  
  ... 생략 ... 
  
      EvTextField(
        title: '식별코드',
        hintText: '식별코드를 입력해 주세요.',
        idController: codeController,
        enableObscure: true,
        limitInputLength: 100,
        isDigitsOnly: true,
        currentFocusNode: secondFocusNode,
        onValueChanged: (text) {
          code.value = text;
        },
      ),
  
  ... 생략 ... 
  
  	}
  }

 

위의 코드의 특징을 몇개 짚어보자. 

1. CodeHandler는 Widget이 Rebuild 시점마다 계속 생성될 필요가 없습니다.
    따라서 Widget 생명주기에서 딱 한번만 CodeHandler를 생성하도록 flutter_hooks의 useMemoized 를 활용했습니다. 

2. 플랫폼중 Android 에만 해당하는 기능이기 때문에 Platform.isAndroid 플래그 안에서만 CodeHandler 동작이 진행됩니다.

 


마무리

Flutter에서 sms autofill 기능은 처음 구현해보았네요! 

생각보다 빠르게 문제 해결을 할 수 있었습니다. 
처음 구현하시는 분들은 제 글을 보고 우여곡절을 줄였으면 합니다. 

그럼 굿럭! 

'flutter' 카테고리의 다른 글

Flutter FCM push 적용기  (2) 2024.12.17
Flutter Webview 연동하기  (0) 2024.09.24
Flutter Mvvm Clean Architecture Guide  (0) 2024.09.13
flutter go_router vs auto_route  (0) 2024.09.11
flutter thread 분석  (0) 2024.06.05
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함