Saving the API Key in gradle.properties
Asked Answered
E

4

45

I am new to android and working on a project where I see that the API key that I got is saved in gradle.properties as :

MyOpenWeatherMapApiKey="1c3ae96f93a0094e8a7chsjdgfid04aed3f10"

And then in build.gradle(module:app) I am adding the following lines :

buildTypes.each {
            it.buildConfigField 'String', 'OPEN_WEATHER_MAP_API_KEY', MyOpenWeatherMapApiKey
      }

So, in my main program I am accessing the data using this api whose URL is got by this piece of code :

final String FORECAST_BASE_URL = "http://api.openweathermap.org/data/2.5/forecast/daily?";
            final String QUERY_PARAM = "q";
            final String FORMAT_PARAM = "mode";
            final String UNITS_PARAM = "units";
            final String DAYS_PARAM = "cnt";
            final String APPID_PARAM = "APPID";
            Uri builtUri = Uri.parse(FORECAST_BASE_URL).buildUpon()
                    .appendQueryParameter(QUERY_PARAM, params[0])
                    .appendQueryParameter(FORMAT_PARAM, format)
                    .appendQueryParameter(UNITS_PARAM, units)
                    .appendQueryParameter(DAYS_PARAM, Integer.toString(numDays))
                    .appendQueryParameter(APPID_PARAM, BuildConfig.OPEN_WEATHER_MAP_API_KEY)
                    .build();
            URL url = new URL(builtUri.toString());

So, my question is that why taking all the tension of doing changes to store the appid in the gradle part. Can't we access directly in the main program only ?

And the second part of my question is what is actually happening in the gradle part especially with the buildTypes.each{} block ?

Emlyn answered 1/3, 2016 at 12:25 Comment(1)
Thanks. Your question helped me to configure my project.Harriot
R
45
  1. The idea of this indirection is to allow you to store API key in files that are not uploaded to the version control: gradle.properties is a local file and should not be stored under the version control, and BuildConfig is a generated class, so it will only be created at build time. It's definitely easier to store the API key somewhere as a plain String, but then you'll have to commit it to the repo.
  2. During build time, Gradle will generate the BuildConfig file to store some build-related constants. You can use buildConfigField command to instruct Gradle to add custom fields into BuildConfig. After the project is built, you can reference these constants inside your source code.
Rufena answered 1/3, 2016 at 12:44 Comment(6)
Is it safe from reverse engineering on apk?Boogeyman
@SumitShukla, it is not, the API key will still end up being a constant string that can easily be located upon decompilation. If you want some value to be safe from reverse engineering then it should live on the server.Rufena
Other similar ways that you can follow: guides.codepath.com/android/Storing-Secret-Keys-in-Android #33134531Lasseter
If you put your API_KEY in your app, then you need to enable proguard to so that the key would be obfuscated. Otherwise a better approach to secure your api_keys is to save them in your server and get it during the runtime.Illume
@SonuSanjeev, I don't think proguard has a way to obfuscate string literals, but I might be wrong.Rufena
@Egor, Thanks for pointing it out. A quick googling thought me proguard obfuscates class names, method names and variable names but not the strings.Illume
D
51

Refer - Complete implementation for storing API_KEY in gradle properties to avoid uploading to Github.

https://richardroseblog.wordpress.com/2016/05/29/hiding-secret-api-keys-from-git/


  1. Add gradle.properties into .gitignore file

  2. Add line in gradle.properties file API_KEY="CopyYourAPI_KEYhere"

  3. Add below line in app/build.gradle within the defaultConfig

    buildConfigField("String", "API_KEY", API_KEY)

  4. Use Key using the following statement

    String API_KEY = BuildConfig.API_KEY;

Copy this wherever you need API_KEY

It will save your efforts to add and remove API_KEY while committing code in Github.

Doddering answered 29/7, 2018 at 16:49 Comment(5)
This is a borderline link-only answer. You should expand your answer to include as much information here, and use the link only for reference.Downhill
Sure, I have added the details in short. If you have any query, please let me know.Doddering
this answer is easy to understand than others, thanks :)Unpolite
This method requires that you remember to add the file to your .gitignore AND remove it from git since it's added by default. Furthermore the project-level file has other settings that you DO want to share with your team. It has its own issues, but the GLOBAL gradle.properties file is better for sensitive keys.Mcguire
What if you want to use the KEY on a different module?Munster
R
45
  1. The idea of this indirection is to allow you to store API key in files that are not uploaded to the version control: gradle.properties is a local file and should not be stored under the version control, and BuildConfig is a generated class, so it will only be created at build time. It's definitely easier to store the API key somewhere as a plain String, but then you'll have to commit it to the repo.
  2. During build time, Gradle will generate the BuildConfig file to store some build-related constants. You can use buildConfigField command to instruct Gradle to add custom fields into BuildConfig. After the project is built, you can reference these constants inside your source code.
Rufena answered 1/3, 2016 at 12:44 Comment(6)
Is it safe from reverse engineering on apk?Boogeyman
@SumitShukla, it is not, the API key will still end up being a constant string that can easily be located upon decompilation. If you want some value to be safe from reverse engineering then it should live on the server.Rufena
Other similar ways that you can follow: guides.codepath.com/android/Storing-Secret-Keys-in-Android #33134531Lasseter
If you put your API_KEY in your app, then you need to enable proguard to so that the key would be obfuscated. Otherwise a better approach to secure your api_keys is to save them in your server and get it during the runtime.Illume
@SonuSanjeev, I don't think proguard has a way to obfuscate string literals, but I might be wrong.Rufena
@Egor, Thanks for pointing it out. A quick googling thought me proguard obfuscates class names, method names and variable names but not the strings.Illume
F
16

Saving the API Key in gradle.properties might not be a great idea. Using the local.properties file will be more convincing. Since local.properties file will by default be added in the git ignore file, I believe this will be a great place to add the API key.

To add the API_key in local properties you can follow these two simple steps below.

Step 1

Edit your local.properties file and add below code

sdk.dir=/Users/Library/Android/sdk
API_KEY=**Your Key**

Step 2

Edit your app-level build.gradle file and add the 'buildConfigField' inside defaultConfig as shown below.

Properties properties = new Properties()
    properties.load(project.rootProject.file('local.properties').newDataInputStream())

buildConfigField "String", "API_KEY", "\"${properties.getProperty('API_KEY')}\""

Note that per this post you will need to add quotes for String types

Step 3

Sync your project with Gradle changes.

Step 4

Rebuild your project from Build->Rebuild Project.

All done!! Now you can access the key by calling BuildConfig.API_KEY

Fungiform answered 6/12, 2021 at 10:36 Comment(0)
K
3

There is a better way

First make sure both build/ and local.properties are added to your .gitignore

build/

# Local configuration file (sdk path, etc)
local.properties

Add your APIKEY xyz123 to your local.properties as follows

apiKey="xyz123"

Next add the following block to the root level of your app build.gradle

def localPropertiesFile = rootProject.file("local.properties")
def localProperties = new Properties()
localProperties.load(new FileInputStream(localPropertiesFile))

Add the following line to the android block of your app build.gradle

buildConfigField("String", "API_KEY", localProperties['apiKey'])

Then, we may call the BuildConfig.API_KEY constant as follows

import app.unicornapp.mobile.android.unicorn.BuildConfig
import app.unicornapp.mobile.android.unicorn.BuildConfig.API_KEY
import retrofit2.http.Query


interface StockApi {
    suspend fun getListings(
        @Query("apikey") apiKey: String
    )

    companion object {
        val API_KEY = BuildConfig.API_KEY
    }

}
Kassie answered 8/2, 2023 at 5:35 Comment(1)
Since Android Gradle Plugin 8.0, the BuildConfig class is not generated by default. You can generate it by adding: buildFeatures { buildConfig true } to build.gradleDunsinane

© 2022 - 2024 — McMap. All rights reserved.