Is there a safe way to manage API keys?

前端 未结 4 1793
死守一世寂寞
死守一世寂寞 2020-12-07 09:18

I am using an API within my app. I currently manage the API key from a java interface

public interface APIContract {
    //The API KEY MUST NOT BE PUBLISH. I         


        
相关标签:
4条回答
  • 2020-12-07 09:19

    1. Store api keys in an xml file

    Put xml file "api_keys.xml" in the directory "res/values/".

    api_keys.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="THE_MOVIE_DB_API_TOKEN">XXXXX</string>
    </resources>
    

    use api keys in java code

    context.getString(R.string.THE_MOVIE_DB_API_TOKEN);
    

    2. Store API keys with help of Gradle and the gradle.properties file

    Example_0 Example_1

    Add the following line to [USER_HOME]/.gradle/gradle.properties

    For Windows OS, an example for Denis user:

    C:\Users\Denis\.gradle
    

    gradle.properties

    MyTheMovieDBApiToken="XXXXX"
    

    Add the following code to the build.gradle file

    build.gradle

    apply plugin: 'com.android.application'
    
    android {
        ...
    
        defaultConfig {
            ...
        }
        buildTypes {
            release {
                ...
            }
        }
        buildTypes.each {
          it.buildConfigField 'String', 'THE_MOVIE_DB_API_TOKEN', MyTheMovieDBApiToken
        }
    }
    

    use api keys in java code

    BuildConfig.THE_MOVIE_DB_API_TOKEN)
    

    3. Store API keys with help of gradle and the system path variable

    Example_0

    Add new system PATH variable THE_MOVIE_DB_API_TOKEN="XXXXX":

    For Windows OS:

    • open system
    • advanced system settings
    • environment variables
    • add new variables to the user variables

    Add the following code to the build.gradle file

    build.gradle

    apply plugin: 'com.android.application'
    
    android {
        ...
    
        defaultConfig {
            ...
        }
        buildTypes {
            release {
                ...
            }
            buildTypes.each {
                it.buildConfigField 'String', 'THE_MOVIE_DB_API_TOKEN', "\"$System.env.THE_MOVIE_DB_API_TOKEN\""
            }
        }
    }
    

    use API keys in java code

    BuildConfig.THE_MOVIE_DB_API_TOKEN
    

    Link to my gist on github

    0 讨论(0)
  • 2020-12-07 09:24

    You can add the key to the gradle.properties file or pass it as an argument

    0 讨论(0)
  • 2020-12-07 09:29

    I put them on the global gradle.properties file on the dev machine or ci server. This way is not part of your project so you shouldn't worry about checking it in your repo, but it's still easily accessible from your gradle files. Global gradle.properties file should be located inside ˜/.gradle on Mac for instance - btw, you should create it if it doesn't exist. Then on your build.gradle file you can reference those properties and, for instance, expose them as buildConfigFields using the same name you used in your gradle.properties file

    buildConfigField 'String', 'API_KEY', maps.api.key
    

    Then on your Java/Kotlin code you can access them as BuildConfig.API_KEY

    0 讨论(0)
  • 2020-12-07 09:38

    Here is another way:

    Place the API key in a file accessible to the build machine/server, we'll call it:

    /usr/api_user/api_key1
    

    With contents:

    myApiKey = abcdefghijklmnopqrstuvwxyz
    

    You will now access it using the `BuildConfig' gradle object. Modify your code to this:

    public interface APIContract {
        //The API KEY MUST NOT BE PUBLISH. It is possible to generate a new one for free from www.themoviedb.org
        //Remove before commit !!!
        String API_KEY = BuildConfig.MY_API_KEY;
        /...
    }
    

    Then in your build.gradle, add something like this:

    buildConfigField "String", "MY_API_KEY", getMyApiKey("myApiKey")
    

    And also add this:

    //return a MY API KEY from a properties file.
    def getMyApiKey(String property){
        Properties properties = new Properties()
        properties.load(new FileInputStream("/usr/api_user/api_key1"))
        return "\"" + properties.getProperty(property) +"\""
    }
    

    You can relocate the API directory location, as you can tell, so that it is not a part of your repo. Of course, then it will have file system dependencies for the build... which you could have a list setup in a CI/CD environment (maybe a tool like Jenkins) to replicate the build files to a private repo, for backup purposes.

    0 讨论(0)
提交回复
热议问题