-
[Android Studio] 내 프로젝트에 사용된 API의 Key를 숨기고 GitHub에 업로드하기Programming (Others)/FrontEnd 2021. 3. 18. 05:48
1년 전 쯤에 학교 수업 프로젝트로 어플리케이션을 만든 적이 있었다.
그 때 네이버 지도 api와 그 외 각종 api를 사용했었는데
그 때 만들었던, COVID-19 관련 유용한 정보를 알려 주는 앱 (이 앱은 비상업적 용도로 제작되었으며, ㈜여기어때컴퍼니가 제공한 '여기어때 잘난체'가 적용되어 있습니다.) 문제는 내가 그 땐 아무것도 모를 때라
(지금이라고 다를 바는 없지만)그런 api의 키 값과 비밀번호 등 중요한 값들을 그대로 코드에 노출한 채 GitHub에 푸시했었다..떡하니 코드 중간에 위치한(...) Key값 그리고 몇달 후, 우연히 그런 행동의 위험성을 경고하는 글을 접하게 되었고, 나도 키를 감춰보고자 이 포스팅을 작성하게 되었다.
0. .gitignore
이럴 때 유용하게 사용되는 것이 바로 gitignore이다. 말 그대로 git ignore, 특정 파일을 무시하고 깃에 푸시한다는 것이다. 사용 방법은 간단하다. .gitignore 파일을 생성하고, 그 안에 숨길 파일명, 확장자 등등을 적어주면 된다.
예 (출처) :
# Package Files #
*.jar *.war *.nar *.ear *.zip *.tar.gz *.rar
### AndroidStudio ###
# Covers files to be ignored for android development using Android Studio.
# Built application files
*.apk *.ap_ *.aab
간단하게 .gitignore 파일의 내용을 생성해주는 사이트도 있다.
www.toptal.com/developers/gitignore
gitignore.io
Create useful .gitignore files for your project
www.toptal.com
해당 사이트에 접속해 현재 프로젝트의 속성(언어, IDE, 프레임워크 등)을 입력하면 알아서 .gitignore에 들어갈 내용을 생성해 준다.
1. 첫 번째 방법 (문자열 리소스 파일 생성하기)
이 것을 이용하여 Key를 감추기 위해서, 다음과 같은 일련의 과정을 수행할 것이다!
1. 문자열 리소스 파일(.xml)을 생성하여 Key값만 따로 빼기
2. 그 파일을 .gitignore에 추가하기
res > values에 key.xml 파일을 생성해 주었다. (파일 이름은 임의로 해도 된다.)
Key값들을 따로 빼서 다음과 같은 양식으로 입력해 준다.
(아래는 키 값이 abcde일 때의 예시이다.)
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="Naver_Map_ID">abcde</string> <string name="Naver_Map_Secret">abcde</string> </resources>
그 다음, 코드의 키값을 참조한 부분을 문자열 리소스 파일을 참조하는 형태로 수정해준다.
문자열 리소스 파일을 참조하는 방법에는 두 가지가 있는데
xml파일의 경우에는 "@string/[string name]"을 입력하면 되고,
그 외 코드 파일의 경우에는 getString(R.string.[string name])을 입력해주면 된다.
..그런데 여기서 문제가 생기고 만다.
getString은 Context나 Activity 안에서만 쓸 수 있는데, 내가 Key값이 필요한 부분은 그 바깥이었던 것.
(API의 값을 불러오기 위해 스레드(AsynTask)를 상속받는 클래스를 따로 만들어서 그 안에다가 코드를 짰었다.)
Resources.getSystem().getString() 함수를 사용하면 된다고는 하나 System Resource만 쓸 수 있다고 한다. (key.xml 파일은 local resource라고 함)
그러므로 key.xml를 별 영향없이 쓸 수 있는 Manifest.xml 파일에서는 해당 방법을 쓰고, 그 외 소스코드 부분은 다른 방법을 사용하기로 한다.
일단 Manifest 파일에서 key값을 넣는 부분을 다음과 같이 수정해 주었다.
<meta-data android:name="com.naver.maps.map.CLIENT_ID" android:value="@string/Naver_Map_ID" />
그리고 app 수준의 .gitignore (Android Studio에서 프로젝트를 만들면 알아서 생성된다)에 key.xml이 있는 경로와 함께 해당 파일명을 추가해준다.
root 수준의 .gitignore 파일에 추가해줘도 상관없다. 대신 경로는 그에 맞게 입력해야 할 것이다.
... /src/main/res/values/key.xml
이렇게 Manifest파일에서의 key값 처리가 끝났다. 그럼 나머지 부분의 key값 처리는 어떻게 해 주어야 할까?
key값이 Context나 Activity 바깥에 있어도 사용할 수 있는 방법이 두 번째 방법이다.
2. 두 번째 방법 (BuildConfig 이용하기)
앱이 빌드되면 BuildConfig라는 파일이 생성된다고 한다. 이 안에는 다양한 상수들이 들어가는데, 이 BuildConfig안에 특정 상수(키 값)가 들어가도록 지정해줌으로써 key값을 따로 분리할 수 있다.
우선, root 수준에서 [아무이름].properties 파일을 하나 생성해준다.
나의 경우 key.properties라는 이름으로 생성했다.
그 파일 안에 [키 이름]="값" 의 형태로 Key들을 입력해 준다.
(아래는 키 값이 abcde일 때의 예시이다.)
# Key Values Naver_Map_ID="abcde" Naver_Map_Secret="abcde" Corona_Num_Key="abcde" Corona_News_Key="abcde"
그 다음, app 수준의 build.gradle에서 다음의 위치에 해당 코드들을 입력해준다.
def keyPropertiesFile = rootProject.file("[아무이름].properties") def keyProperties = new Properties() keyProperties.load(new FileInputStream(keyPropertiesFile)) android { ... defaultConfig { ... buildConfigField("String", "Naver_Map_ID", keyProperties['Naver_Map_ID']) buildConfigField("String", "Naver_Map_Secret", keyProperties['Naver_Map_Secret']) buildConfigField("String", "Corona_Num_Key", keyProperties['Corona_Num_Key']) buildConfigField("String", "Corona_News_Key", keyProperties['Corona_News_Key']) ... } buildTypes { ...
그 후, 키 값이 필요한 소스 코드에 BuildConfig.[키 이름] 형태로 참조하여 사용해준다.
connection.setRequestProperty("X-NCP-APIGW-API-KEY-ID", BuildConfig.Naver_Map_ID) connection.setRequestProperty("X-NCP-APIGW-API-KEY", BuildConfig.Naver_Map_Secret)
이 때, Android Studio에서 BuildConfig.를 쳤는데 목록에 자신이 등록한 Key가 보이지 않는다고 당황하지 말자.
처음에 언급했듯이, 해당 상수는 빌드를 해야 생성된다. 그냥 빨간줄이 그여도 임의로 값을 입력하고 빌드를 하면, 오류는 말끔히 사라진다.
마지막으로 root 수준의 .gitignore 파일에 아까 생성한 [아무이름].properties를 추가한다.
... key.properties
3. Git에 Push하기
나는 이미 깃에 API Key가 노출된 상태로 push를 해버리는 바람에 여태까지의 commit 내용을 전부 지우고 새로 commit해야 했었다. 이를 수행하는 방법은 이 글을 참조하기를 바란다.
이렇게 commit과 push를 하고 나면, GitHub에 다음과 같이
key.properties와 key.xml 파일이 푸시되지 않은 것을 확인할 수 있다.