API网关是否可以在URL中而不是在标头中传递API密钥?

问题描述 投票:3回答:3

要使用aws生成的“ API KEY”访问AWS API Gateway,必须将其密钥作为'x-api-key'标头传递。我知道您可以通过“ curl”,“ wget”,邮递员和编程方式来实现。

问题:可以通过任何方式将密钥作为url的一部分进行传递,以便没有curl / wget / postman等的人可以仅使用浏览器来调用它吗?换句话说,有没有一种方法可以创建一个URL,例如下面的命令来执行api-key auth?

https://<api-key>@www.aws-api-gw-url.com/path/to/get_my_data

https://www.aws-api-gw-url.com/path/to/get_my_data?x-api-key=<api-key>

在官方docs或在网上搜索后,我没有看到任何实现此目的的方法。我也尝试了各种失败的组合。

excel amazon-web-services browser aws-api-gateway
3个回答
4
投票

API密钥可能无法在URL中传递。这是设计使然。如果API密钥在URL中,则可以看到URL的任何内容都可以轻松捕获API密钥并使用它来获得对API的未授权访问。这将包括用户查看地址栏以及在某些情况下浏览器中运行的其他脚本代码。


0
投票

尽管可能不建议这样做,但是您可以通过创建自己的API网关lambda授权方来在查询字符串中传递API密钥。使用以下内容创建一个lambda函数:

exports.handler = function(event, context, callback) {
    callback(null, {
        principalId: "x-api-key",
        usageIdentifierKey: event.queryStringParameters["x-api-key"],
        policyDocument: {
            Version: "2012-10-17",
            Statement: [{
                Action: "execute-api:Invoke",
                Effect: "Allow",
                Resource: event.methodArn
            }]
        }
    });
};

上面的代码基本上只是从名为x-api-key的查询参数映射API密钥。 API网关将负责验证API密钥并在无效时以403 Forbidden进行响应。


0
投票

[当调用API的客户端无法在标头中传递apikey时,例如,这是第三方服务的webhook,此lambda函数解决了该问题。

我们无法读取POST请求正文中的apikey,因为lambda授权者无权访问请求正文。

剩下两个解决方案:

  1. 将apikey作为查询字符串参数读取(最危险的方式)
  2. 将apikey读取为Basic Auth标头的“密码”字段,在这种情况下,请忽略“用户”字段。是的,这是一个肮脏的骇客,但是如果客户端支持基本身份验证,它就可以使用]
  3. 我们使用这两种解决方案,并在头中添加了读取apikey的功能(适用于可以发送头的客户端)。>>

    apikey的读取优先级如下(如果客户端一次以三种方式发送apikey,则为:]

  1. 在标题“ x-api-key”中
  2. 在“密码”字段中的基本身份验证
  3. 在querystring参数“ x-api-key”中必须为此函数创建类型为Request的授权者。不要使用缓存,否则会出现错误401见https://docs.aws.amazon.com/apigateway/api-reference/resource/authorizer/#identitySource该错误是由于需要一次填写三个参数
  4. 如果缓存是必不可少的,则只需选择三个apikey读取选项之一。我没有找到其他解决方案

function parseApiKey(str) {
    if (!str)
      return;
    var m1 = str.match(/Basic (.+)/i);
    if (!m1)
        return;
    var decodeStr = Buffer.from(m1[1], 'base64').toString();
    var m2 = decodeStr.match(/(.*):(.+)/);
    if (m2) {
        return m2[2];
    }
}

exports.handler = function (event, context, callback) {
    callback(null, {
        'principalId': "Any value",
        'policyDocument': {
            'Version': '2012-10-17',
            'Statement': [{
                    'Action': 'execute-api:Invoke',
                    'Effect': 'Allow',
                    'Resource': event.methodArn
                }]
        },
        'usageIdentifierKey': 
                event.headers["x-api-key"] 
                || parseApiKey(event.headers["Authorization"]) 
                || event.queryStringParameters["x-api-key"] 
                || ""
    });
};
© www.soinside.com 2019 - 2024. All rights reserved.