发布到 api 网关时无法解析“授权标头中不是有效的键=值对(缺少等号)”

问题描述 投票:0回答:15

我创建了一个 api 网关来将数据放入我的 s3 存储桶中。当我在控制台中测试它时,它工作没有问题。即使当我在授权者测试中测试我的令牌时,它也会返回“允许”,因此我的令牌没有任何问题。我的令牌验证是

^Bearer [-0-9a-zA-z\.]*$

所以我用于生成标头的 python 代码如下所示:

headers = {
    "Authorization": "Bearer " + token,
    "Content-type": "application/json"
}

我的其余代码是:

response = requests.post(url, headers=headers, data={"id":"0678a93d-ee8c-4db5-a831-1e311be4f04b", "test":"12345"})
print(response.text)

我收到的错误消息是 "{"message":"'{My Token}' 授权标头中不是有效的键=值对(缺少等号):'Bearer {My Token}'。"}"

我的网址如下所示:

https://my-api-gateway.amazonaws.com/MyStage,我在我的资源中使用 {proxy+}。我注意到,如果我将标头从 Content-type 更改为 Accept,它会给我同样的错误,但如果我也将我的 url 更改为 https://my-api-gateway.amazonaws.com/MyStage/any- Arbitration-字符串/,我得到一个

   {"response":{"status":"VALID", "message": "success"}} 

但是该文件没有显示在我的 s3 存储桶中。我该如何解决这个问题?

python amazon-web-services aws-api-gateway
15个回答
88
投票

当解析的 URL 不正确时,我遇到过此错误。 (或者没有代理但 URL 不正确。)


18
投票

对我来说,它不起作用的原因是因为我在更改集成时没有重新部署。

因此,如果您使用 terraform 创建资源,则需要包含

triggers
部分。请参阅:https://www.terraform.io/docs/providers/aws/r/api_gateway_deployment.html#redeployment-triggers

如果您使用的是 UI,请检查:


8
投票

我解决了。我将方法更改为来自根资源(而不是不必要的 {proxy+},并且还注意到我的 python 方法不正确。我有

response = requests.post(url, headers=headers, data=my_json)
,但数据只接受字符串。我必须使用
requests.post(url, headers=headers, json=my_json)
requests.post(url, headers=headers,data=json.dumps(my_json))


5
投票

我也遇到过同样的问题。对我来说,问题是由于网址区分大小写造成的。请确保每个单词的拼写和大小写均正确。


3
投票

路径中使用“{proxy+}”时,还需要添加根路径。添加“{proxy+}”是 API 网关了解您正在使用 Lambda 代理集成的方式。所以不要遗漏它。

即.,

Type: AWS::Serverless::Function
    Properties:
       Events:
         ProxyResource:
           Type: Api
           Properties:
             RestApiId: ...
             Path: /{proxy+}
             Method: ANY
         RootResource:
           Type: Api
           Properties:
             RestApiId: ...
             Path: /
             Method: ANY

3
投票

就我而言非常相似, 使用第三个 api 付款在 request METHOD 上设置错误,我使用 POST 而不是 DELETE。啊,我的错。


2
投票

如果您使用的是 aws-api-gateway。
如果 API 在 aws 控制台的 api-gateway 中工作正常,但在邮递员中无法工作。

机会是

you might have forgotten to deploy your api in api gateway


1
投票

对于邮递员代码生成器,请确保从 URL 中删除不必要的空格,这是我的问题


1
投票

就我而言,当我用 PATCH 替换 POST 时,它就起作用了

curl_setopt_array($curl, array(
...
CURLOPT_CUSTOMREQUEST => 'PATCH',
...

1
投票

除了Will的回答之外,还请确保您调用的URL与API网关中定义的大小写相同(小写或其他)。网址区分大小写


0
投票

我在运行 AWS.config.update 时遇到了同样的错误。我有一个额外的空格字符,它给出了这个错误。只是将其发布在这里,因为它不清楚 - 但我确信很容易发现。


0
投票

就我而言,我选择了错误的方法。 请检查您的请求方式


0
投票

对我来说,问题同样是一个不正确的 URL。我的端点应该接受另一个 URL 作为路径参数;我应用了 Pyton 的

urllib.parse.quote(url)
而不是
urllib.parse.quote_plus(url)
,所以我向 https://apigw.playground.sweet.io/gameplay/pack/https%3A//collectible.playground.sweet.io 发出请求/series/BjqGOJqp 而不是 https://apigw.playground.sweet.io/gameplay/pack/https%3A%2F%2Fcollectible.playground.sweet.io%2Fseries%2FBjqGOJqp 🤕


0
投票

当我得到这个消息时,我已经脑残了,正在访问 apigateway 根,而不是带有处理程序的端点。


0
投票

当我尝试获取不存在的端点来测试我的网关时,我收到了相同的消息。

我以为是令牌错误,但不是。这是因为我没有定义默认网关响应而导致的。

为了解决这个问题,我在下面创建了此代码,通过 terraform 将相同的标头添加到多个错误/状态代码中。

variable "http_responses" {
  type    = list(object({
    name          = string
    status_code   = string
    response_type = string
  }))
  default = [
    { name = "AccessDenied",                    status_code = "403", response_type = "ACCESS_DENIED" },
    { name = "ApiConfigurationError",           status_code = "500", response_type = "API_CONFIGURATION_ERROR" },
    { name = "AuthorizerConfigurationError",    status_code = "500", response_type = "AUTHORIZER_CONFIGURATION_ERROR" },
    { name = "AuthorizerFailure",               status_code = "500", response_type = "AUTHORIZER_FAILURE" },
    { name = "BadRequestBody",                  status_code = "400", response_type = "BAD_REQUEST_BODY" },
    { name = "BadRequestParameters",            status_code = "400", response_type = "BAD_REQUEST_PARAMETERS" },
    { name = "ExpiredToken",                    status_code = "403", response_type = "EXPIRED_TOKEN" },
    { name = "IntegrationFailure",              status_code = "500", response_type = "INTEGRATION_FAILURE" },
    { name = "IntegrationTimeout",              status_code = "504", response_type = "INTEGRATION_TIMEOUT" },
    { name = "InvalidApiKey",                   status_code = "403", response_type = "INVALID_API_KEY" },
    { name = "InvalidSignature",                status_code = "403", response_type = "INVALID_SIGNATURE" },
    { name = "MissingAuthenticationToken",      status_code = "403", response_type = "MISSING_AUTHENTICATION_TOKEN" },
    { name = "QuotaExceeded",                   status_code = "429", response_type = "QUOTA_EXCEEDED" },
    { name = "RequestTooLarge",                 status_code = "413", response_type = "REQUEST_TOO_LARGE" },
    { name = "ResourceNotFound",                status_code = "404", response_type = "RESOURCE_NOT_FOUND" },
    { name = "Throttled",                       status_code = "429", response_type = "THROTTLED" },
    { name = "Unauthorized",                    status_code = "401", response_type = "UNAUTHORIZED" },
    { name = "UnsupportedMediaType",            status_code = "415", response_type = "UNSUPPORTED_MEDIA_TYPE" },
    { name = "WafFiltered",                     status_code = "403", response_type = "WAF_FILTERED" },
    { name = "DEFAULT_4XX",                     status_code = "", response_type = "DEFAULT_4XX" },
    { name = "DEFAULT_5XX",                     status_code = "", response_type = "DEFAULT_5XX" },

  ]
}

resource "aws_api_gateway_gateway_response" "http_responses" {
  for_each = { for response in var.http_responses : "${response.name}-${response.status_code}" => response }

  rest_api_id   = aws_api_gateway_rest_api.my_api.id
  status_code   = each.value.status_code
  response_type = each.value.response_type

  response_templates = {
    "application/json" = "{\"message\":$context.error.messageString}"
  }

  response_parameters = {
    "gatewayresponse.header.Access-Control-Allow-Headers" = "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
    "gatewayresponse.header.Access-Control-Allow-Methods" = "'GET,OPTIONS'"
    "gatewayresponse.header.Access-Control-Allow-Origin"  = "'*'"

  }
}

现在,当我尝试获取不存在的端点时,我得到以下响应:

   {
   "field" : null,
   "exceptionClass" : "ResponseStatusException",
   "message" : "field não encontrado",
   "statusCode" : 404,
   "statusText" : "404 NOT_FOUND"
}

是吗。

© www.soinside.com 2019 - 2024. All rights reserved.