【问题标题】:AWS "Missing required client configuration options" exception with Yii::createObject() default configurationYii::createObject() 默认配置的 AWS“缺少所需的客户端配置选项”异常
【发布时间】:2017-07-05 01:22:23
【问题描述】:

我正在尝试使用 Yii 2 框架、托管在 AWS 上的 DynamoDB 数据库和适用于 PHP 的 AWS 开发工具包创建一个简单的 Web 应用程序。我只是在数据库中保存/检索电影详细信息。

(为了在此处复制代码,我不会复制我真正的 AWS 密钥/秘密。)

当我像这样创建 Aws\Sdk 对象时,一切都按我的意愿工作:

$sdk = new Aws\Sdk([
    'region'   => 'us-west-2',
    'version'  => 'latest',
    'credentials' => [
        'key'     => 'KEYKEYKEYKEYKEYKEYKE',
        'secret'  => 'SECRETSECRETSECRETSECRETSECRETSECRETSECR'
    ]
]);
$dynamodb = $sdk->createDynamoDb();

但我想通过 Yii::createObject() 方法利用 Yii 的 默认配置,这样我就不必在创建的每个地方都指定区域、版本和凭据Aws\Sdk 对象。所以,根据Yii documentation,我已经保存到我的应用程序配置中:

\Yii::$container->set('Aws\Sdk', [
    'region'      => 'us-west-2',
    'version'     => 'latest',
    'credentials' => [
        'key'     => 'KEYKEYKEYKEYKEYKEYKE',
        'secret'  => 'SECRETSECRETSECRETSECRETSECRETSECRETSECR'
    ]
]);

现在无论我在哪里创建 Aws\Sdk 对象,我的代码都如下所示:

$sdk = Yii::createObject('Aws\Sdk');
$dynamodb = $sdk->createDynamoDb();

但是,当我这样做时,我从 AWS 收到关于“缺少所需的客户端配置选项”的 InvalidArgumentException。如果我在分配var_dump() $sdk 变量后立即对其进行分配,我可以看到该对象具有所需的区域、版本和凭据属性,但是我分配$dynamodb 变量的下一行会引发异常。

我希望有人能告诉我哪里出错了。

【问题讨论】:

    标签: php amazon-web-services yii2 amazon-dynamodb aws-sdk


    【解决方案1】:

    首先,您不应该将凭据放入您的代码中。我推荐以下:

    • 如果您在 EC2 实例上运行此代码,请改为应用 IAM 角色。使用角色,您可以准确声明将在实例中运行的任何 CLI/SDK 调用的权限。 SDK去打电话时,it will contact the instance metadata server and get a set of temporary credentials。当然,这一切都是透明地发生的,您无需做任何事情。由于凭证会在一段时间后过期(当这种情况透明地发生时,您的 SDK 当然会获取新凭证)。这是最佳选择,因为您不再需要担心凭据,其他 SDK 或 CLI 可以使用它,而且这一切都是临时的。
    • Use a credentials file。只有当您的代码在 AWS 领域之外并且无法使用 IAM 角色时,您才应该真正这样做。虽然您的凭据变得更加集中,但它们至少不是您的代码库的一部分,它们可能会被泄露。此外,它还使您可以轻松使用其他语言,并且仍然可以自动提取凭据。

    现在进入另一部分:

    \Yii::$container->set('Aws\Sdk', [
        'region'      => 'us-west-2',
        'version'     => 'latest',
        'credentials' => [
            'key'     => 'KEYKEYKEYKEYKEYKEYKE',
            'secret'  => 'SECRETSECRETSECRETSECRETSECRETSECRETSECR'
        ]
    ]);
    

    这不是你想的那样,如果你看看the source code

     * If a class definition with the same name already exists, it will be overwritten with the new one.
     * You may use [[has()]] to check if a class definition already exists.
     *
     * @param string $class class name, interface name or alias name
     * @param mixed $definition the definition associated with `$class`. It can be one of the following:
     *
     * - a PHP callable: The callable will be executed when [[get()]] is invoked. The signature of the callable
     *   should be `function ($container, $params, $config)`, where `$params` stands for the list of constructor
     *   parameters, `$config` the object configuration, and `$container` the container object. The return value
     *   of the callable will be returned by [[get()]] as the object instance requested.
     * - a configuration array: the array contains name-value pairs that will be **used to initialize the property**
     *   **values of the newly created object** when [[get()]] is called. The `class` element stands for the
     *   the class of the object to be created. If `class` is not specified, `$class` will be used as the class name.
     * - a string: a class name, an interface name or an alias name.
     * @param array $params the list of constructor parameters. The parameters will be passed to the class
     * constructor when [[get()]] is called.
     * @return $this the container itself
     */
    

    注意“**”标记的区域。换句话说,第二个参数不是一组可能是您想要的构造函数参数,而是在调用构造函数后将设置的参数数组。相反,您希望第二个参数为空白,第三个参数为数组,例如:

    \Yii::$container->set('Aws\Sdk', [], [[
        'region'      => 'us-west-2',
        'version'     => 'latest'
    ]]);
    

    数组中的数组看起来有点奇怪,但这是因为参数数组基本上按索引进行索引,并将每个参数设置为位置参数。希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-11-06
      • 2019-12-30
      • 1970-01-01
      • 2019-08-04
      • 1970-01-01
      • 1970-01-01
      • 2019-10-29
      相关资源
      最近更新 更多