안녕하세요. 우아한형제들 배민앱개발팀에서 배달의민족 안드로이드 앱을 개발을 하고 있는 나동호입니다. 구글플레이에서 보안 및 개인 정보 보호 정책을 강화하면서 민감한 권한을 제거하며 겪은 이야기를 작성한 글입니다. 이 글에서 나온 버전 코드 및 몇몇 정보들은 실제와는 차이가 있을 수 있습니다.

구글플레이에서 꼭 지켜야 할 정책 2가지

구글플레이에서는 지켜야 할 많은 정책들은 있지만 API 레벨 26 이상 지정통화 기록 및 SMS 사용 권한 제한은 꼭 지켜야 하는 정책입니다. ‘API 레벨 26 이상 지정’ 정책을 지키지 않으면 2018년 8월부터는 더 이상 앱을 새로 출시할 수 없었고, 2018년 11월부터는 기존 앱을 업데이트를 할 수도 없었습니다. ‘통화 기록 및 SMS 사용 권한 제한’ 정책은 구글에 승인되지 않은 앱이 민감한 권한들을 포함한 경우 2019년 1월 9일에 구글플레이에서 삭제되었고, 유예기간을 얻은 앱들도 2019년 3월 9일부로 삭제되게 됩니다.


API 레벨 26 이상 지정 (2017년 12월 공지)

  • 2018년 8월 : 새 앱에서 API 레벨 26(Android 8.0) 이상을 대상으로 지정해야 합니다.
  • 2018년 11월 : 기존 앱 업데이트에서 API 레벨 26 이상을 대상으로 지정해야 합니다.
  • 2019년 이후 : 매년 targetSdkVersion 요구 사항이 향상될 것입니다. 새 안드로이드 디저트 출시 이후 1년 이내에 새 앱 및 앱 업데이트에서 해당 API 레벨 이상을 대상으로 지정해야 합니다.


통화 기록 및 SMS 사용 권한 제한 (2018년 10월 공지)

  • 2019년 1월 9일 : 승인되지 않은 앱은 통화 기록 및 SMS 권한을 제거해야 합니다.
  • 2019년 3월 9일 : 권한 요청 양식을 제출하여 기한 연장을 한 앱도 통화 기록 및 SMS 권한을 제거해야 합니다.

SMS 권한을 제거하자

구글플레이에 출시된 배달의민족 앱은 위의 두 정책 중 ‘API 레벨 26 이상 지정’은 이미 준수하고 있는 상태였습니다. 이젠 남은 하나인 ‘통화 기록 및 SMS 사용 권한 제한’ 정책만 지키면 됩니다. ‘통화 기록 및 SMS 사용 권한 제한’ 정책은 전화나 문자를 주 기능으로 하는 앱이 아니면 해당 권한을 획득할 수 없기 때문에 배달의민족 앱에서도 기존에 획득하고 있던 SMS 권한을 제거해야 합니다.

SMS 권한을 제거하기 전에 배달의민족 앱에서 이 권한이 사용되는 이유를 살펴보면, 회원가입 시 사용자에게 휴대폰 인증을 조금이라도 편하게 만들기 위해서 ‘인증번호 자동 입력’ 기능을 제공하고 있기 때문입니다. 그래서 저희는 여전히 이 기능을 제공하기를 원했고 구글에서는 그 대안으로 SMS Verification API를 사용하라고 제시하고 있습니다.

SMS Verification API 적용은 샘플 코드에 쉽게 나와있어서 SmsRetriever를 사용해서 문자를 수신하도록 변경했습니다. 코드는 샘플과 크게 다르지 않아 여기에서 확인하실 수 있습니다. SmsRetriever 코드 적용 이외에도 SMS 문자 수신을 위해서는 문자 형식도 필수적으로 지켜줘야 합니다.


문자 형식

  • <#> 으로 시작해야 한다.
  • 11자 해시 문자열로 끝나야 한다.
  • 140 byte 이하여야 한다.

문자에서 해시 문자열을 간단히 얻을 수 있도록 구글에서는 명령어를 제시하고 있습니다. 그러나 맥에서 sha256sum 명령어가 포함되어 있지 않아 shasum을 사용하여 가져오도록 변경했습니다.

$ keytool -exportcert -alias androiddebugkey -keystore ~/debug.keystore | xxd -p | tr -d "[:space:]" | echo -n com.example.myapp cat | shasum -a 256 | tr -d "[:space:]-" | xxd -r -p | base64 | cut -c1-11

위의 명령어로 얻은 sUgLwse5ShX 해시 값을 문자 끝에 붙여 아래와 같이 인증문자를 전송하게 됩니다.

<#>
[배달의민족] 인증번호 1178 를 입력하세요.
sUgLwse5ShX

이젠 AndroidManifest.xml에서 RECEIVE_SMS 권한을 제거합니다. SMS 권한도 제거했으니 구글플레이에 배포를 진행해봅니다.

뭐? 아직도 민감한 권한이 있다고?

구글 플레이에 SMS 권한을 제거한 버전을 배포했지만 여전히 민감한 권한이 있다고 경고하고 있습니다.

googleplay-permission-warning-popup


만약 새 버전 출시하기를 한다면 아래의 경고도 계속 보실 수 있습니다. googleplay-permission-warning-form

이런 경고가 계속 표시되는 이유를 확인해 봤더니 구글플레이에서 Multiple Apks 지원하면 출시되고 있는 모든 버전에 대해서 대응이 되어야 한다고 합니다. 현재 배달의민족 앱은 2개의 Apk가 출시되어 있는 상태입니다. 하나는 API19 이상을 지원는 버전과 다른 하나는 API15 이상 ~ API19 미만을 지원하는 버전입니다. 이제부터 편의상 ‘API19 이상’을 지원하는 버전은 ‘현재 출시 버전’, ‘API15 이상 ~ API19 미만’을 지원하는 버전은 ‘과거 유지 버전’이라고 하겠습니다.

‘현재 출시 버전’은 방금 업데이트를 하면서 SMS 권한이 제거되었지만 ‘과거 유지 버전’은 아직 권한이 제거되지 않기 때문에 위와 같은 경고가 발생한 것입니다.

  • 현재 출시 버전 : SMS 권한 제거됨 (API19 이상)
  • ‘과거 유지 버전 : SMS 권한 사용중 (API15 이상 ~ API19 미만)

이제 원인을 알았으니 앱에서 SMS 권한을 제거하고 구글 플레이에 업로드를 준비해봅니다.

앗! 그런데 앱 버전 코드는 어떻게 하지?

‘과거 유지 버전’을 빌드 하려고 했더니 버전 코드를 결정하는데 문제가 발생했습니다.

구글플레이에 앱을 출시할 때 동일한 버전 코드는 업로드를 할 수 없기 때문에 버전 코드는 최소 +1 이상을 올려야 합니다. 배달의민족 앱도 지금까지 앱을 출시하면서 버전 코드를 +1씩만 올렸기 때문에 ‘과거 유지 버전’을 업데이트할 수 있는 버전 코드의 여유 범위가 없었습니다. 만약 여기서 기존과 같이 버전 코드를 +1을 하게 되면 ‘과거 유지 버전’이 ‘현재 출시 버전’보다 더 높은 버전 코드를 갖게 되어 기능적으로 다운그레이드가 될 가능성이 있고, 구글플레이에 출시를 하지 못할 수도 있습니다.

old-version-code-error


그래서 지금의 버전 코드 규칙으로는 ‘현재 출시 버전’과 ‘과거 유지 버전’ 모두 배포를 다시 해야하는 상황이었습니다. 또한 이번과 같이 ‘과거 유지 버전’을 업데이트해야 하는 상황이 다시 발생할 가능성도 고려해야 했습니다. 이러한 불상사를 대비하기 위해서 안드로이드 Multiple Apks 가이드 문서에서 제안하는 버전 코드 규칙을 차용하기로 했습니다. 배달의민족 앱은 이미 버전 코드가 700 이상이었고 기존 버전 코드를 유지할 생각이기 때문에 App-Version 영역을 4자리로 변경하여 사용했습니다. 여기서 알아둬야 할 것은 버전 코드는 최대 21억까지 사용이 가능하다는 사실입니다.

version-code-format

새로운 버전 코드 규칙에 따라 ‘현재 출시 버전’은 버전 코드가 19000730이고, ‘과거 유지 버전’은 15000720으로 Apk를 생성하게 했습니다. 앞으로는 ‘현재 출시 버전’이 ‘과거 유지 버전’보다 항상 높은 버전 코드이기 때문에 기능적으로 다운그레이드 되는 현상은 일어날 수 없게 되었습니다.

잠깐! 최종 빌드를 하기 전에 targetSdkVersion이 26 이상인지 확인해보세요. 만약 ‘과거 유지 버전’이 26 미만이라면 ‘API 레벨 26 이상 지정’ 정책으로 구글플레이에서 Apk를 업로드할 때 아래와 같은 오류를 보실 수 있습니다.

targetsdkversion-26-warning

마무리~ 이젠 진짜 출시!

새로운 버전 코드와 함께 SMS 권한이 제거된 Apk 2개를 구글플레이에 출시해봅니다. 이제는 더 이상 민감한 권한이 있다는 경고는 나타나지 않게 되었습니다. 배달의민족 앱이 구글플레이에서 삭제되는 일도 없어졌습니다.

안드로이드는 점점 보안 및 개인정보 보호가 강화되고 있습니다. 구글이 정한 정책을 지키지 않으면 더 이상 앱을 출시를 하지 못하거나 구글플레이에서 앱이 삭제되는 강력한 패널티를 받게 될 수 있습니다. 이런 패널티를 받지 않으려면 앞으로도 계속 안드로이드 정책에 주의를 기울여야 하고, Multiple Apks를 지원하고 있다면 언제든 정책 변경에 대한 대응을 할 수 있도록 앱에 맞는 적절한 버전 코드 규칙을 사용해야 합니다.

오늘도 모든 개발자 분들이 소중한 앱을 지킬 수 있기를 바랍니다.