【问题标题】:Is there a safe way to manage API keys?有没有一种安全的方法来管理 API 密钥?
【发布时间】:2015-10-14 19:31:59
【问题描述】:

我在我的应用程序中使用API。我目前从 java 接口管理 API 密钥

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 = "abcdefghijklmnopqrstuvwxyz";
    /...
}

这可以完成工作。我可以使用APIContract.API_KEY 访问密钥,但正如您在评论中看到的那样,如果我使用 git 和公共存储库(我不打算发布此密钥),这是不安全的。

所以这是我的问题:是否可以将此密钥移动到另一个我可以从我的应用程序轻松访问但不会提交的地方?

我发现这个 thread 使用 gradle 来存储密钥,但我需要提交 build.gradle 文件,所以它不能完成这项工作。

有人知道如何解决这个问题吗?我在 stackoverflow 中没有发现类似的问题,但也许我错过了一些东西

编辑 我喜欢将密钥移到任何 Java 代码之外的想法,因为其他人(可能是非技术人员)可以轻松管理自己的密钥。我正在考虑使用像 settings.gradle 这样的 gradle 文件。

【问题讨论】:

  • 如果你放在一个单独的(静态)类中,去掉key,提交,添加key,在类上加上“不跟踪”怎么办?
  • 当然,但外部人员管理他们的密钥会很棘手(见编辑)。我正在考虑一些真正可访问且易于修改的东西(例如在根目录中)
  • 为什么会很棘手?他们只需添加一次该密钥即可。

标签: android android-gradle-plugin


【解决方案1】:

1。将 api 密钥存储在 xml 文件中

将xml文件“api_keys.xml”放到“res/values/”目录下。

api_keys.xml

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

在 java 代码中使用 api 键

context.getString(R.string.THE_MOVIE_DB_API_TOKEN);

2。借助 Gradle 和 gradle.properties 文件存储 API 密钥

Example_0 Example_1

将以下行添加到 [USER_HOME]/.gradle/gradle.properties

对于 Windows 操作系统,以 Denis 用户为例:

C:\Users\Denis\.gradle

gradle.properties

MyTheMovieDBApiToken="XXXXX"

将以下代码添加到 build.gradle 文件中

build.gradle

apply plugin: 'com.android.application'

android {
    ...

    defaultConfig {
        ...
    }
    buildTypes {
        release {
            ...
        }
    }
    buildTypes.each {
      it.buildConfigField 'String', 'THE_MOVIE_DB_API_TOKEN', MyTheMovieDBApiToken
    }
}

在 java 代码中使用 api 键

BuildConfig.THE_MOVIE_DB_API_TOKEN)

3。借助 gradle 和系统路径变量存储 API 密钥

Example_0

添加新的系统路径变量THE_MOVIE_DB_API_TOKEN="XXXXX"

对于 Windows 操作系统:

  • 开放系统
  • 高级系统设置
  • 环境变量
  • 为用户变量添加新变量

将以下代码添加到 build.gradle 文件中

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\""
        }
    }
}

在 java 代码中使用 API 密钥

BuildConfig.THE_MOVIE_DB_API_TOKEN

Link to my gist on github

【讨论】:

  • 您能否解释一下将密钥存储在gradle.properties 文件中本质上是如何隐藏值的?我想我仍然需要明确地不在我的.gitignore 文件中包含这个文件(假设我使用的是 Git)。那是对的吗?我还要注意,我对 Gradle 以及所有文件之间的关系知之甚少。任何见解都值得赞赏!
  • @coolDude 是的,如果您的 gradle.properties 文件将存储在您的应用程序的存储库中,您将在您的 .gitignore 中包含此文件。在这篇文章中,它描述了将属性存储在本地计算机的用户目录中的 .gradle 文件夹中。
  • 注意 - 您可能需要重建项目才能访问 BuildConfig.THE_MOVIE_DB_API_TOKEN
【解决方案2】:

这是另一种方式:

将 API 密钥放在构建机器/服务器可访问的文件中,我们称之为:

/usr/api_user/api_key1

有内容:

myApiKey = abcdefghijklmnopqrstuvwxyz

您现在将使用 `BuildConfig' gradle 对象访问它。将您的代码修改为:

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;
    /...
}

然后在你的 build.gradle 中,添加如下内容:

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

还要加上这个:

//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) +"\""
}

如您所知,您可以重新定位 API 目录位置,使其不属于您的存储库。当然,然后它将具有构建的文件系统依赖项......您可以在 CI/CD 环境(可能是像 Jenkins 之类的工具)中设置一个列表,以将构建文件复制到私有存储库,以进行备份。

【讨论】:

  • 我应该在duild.gradle 中定义def getMyApiKey(String property) 函数吗?
  • 是的 - “buildConfigField 不应该在同一个块中 - 它应该是您在“Android”块中构建应用程序的位置
【解决方案3】:

您可以将密钥添加到 gradle.properties 文件或将其作为参数传递

【讨论】:

  • 但是可以提交gradle.properties文件。我可以将它添加到.gitignore,但我将无法使用它来存储其他属性
  • 然后将其作为参数传递
【解决方案4】:

我将它们放在开发机器或 ci 服务器上的全局 gradle.properties 文件中。这种方式不是您项目的一部分,因此您不必担心在您的 repo 中检查它,但它仍然可以从您的 gradle 文件中轻松访问。 例如,全局 gradle.properties 文件应位于 Mac 上的 ˜/.gradle 内 - 顺便说一句,如果它不存在,您应该创建它。 然后在您的 build.gradle 文件中,您可以引用这些属性,例如,使用您在 gradle.properties 文件中使用的相同名称将它们公开为 buildConfigFields

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

然后在您的 Java/Kotlin 代码中,您可以通过 BuildConfig.API_KEY 访问它们

【讨论】:

    猜你喜欢
    • 2014-03-13
    • 2019-02-17
    • 1970-01-01
    • 2021-10-16
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多