web-dev-qa-db-ja.com

AWS API GatewayOPTIONSリクエストは500エラーを返します

私はAPIGatewayとLambdaを初めて使用します。 Node.jsExpressベースのAPIをラムダにデプロイしようとしています。私はawslabsの aws-serverless-expressの例 を使用しています。そのため、AWS構成の多くは自動的に作成されました。

私のAPIはAPIゲートウェイを介して正しく機能しているようです。私の投稿とgetメソッドは正常に機能します。ただし、CORSをサポートする必要があります。私のアプリケーションはOPTIONSリクエストに対して正しいCORS応答を返すはずですが、AWSでは機能していません。

最終的に、私が何をしても、オプション要求に対して500の応答を受け取ります。これらの500個のエラーに関する情報を取得する方法を理解できませんでした。何が原因なのかわかりません。

これは500応答の本文です{"message": "Internal server error"}

応答ヘッダーは次のとおりです。

content-length:36

content-type:application/json

日付:2017年7月9日日曜日17:56:24 GMT

ステータス:500

経由:1.19af17e5a616bfc9ac07fc7e415ade9e6.cloudfront.net(CloudFront)

x-amz-cf-id:1_AZmkLqf1rjkog2MRtvcBAe54aIZdPWmNApBTwG48Af-v_g9WHkZw ==

x-amzn-requestid:ec216a62-64cf-11e7-ad2b-4f1e96508dba

x-cache:cloudfrontからのエラー

OPTIONSリクエストがLambdaのアプリに到達していないことは間違いありません。

API Gateway(および私のアプリ)を使用してCORSを構成してみました。すべてのオリジンを許可するように構成しようとしています。

この問題をデバッグするために私が調べたり実行したりできることがあれば、

編集:

この問題をデバッグするために、APIゲートウェイのCloudWatchへのログインを有効にしようとしました。

CloudWatch configuration for the API Gateway

その後、CloudWatchに次の2つのゲートウェイルックインログが表示されます。

enter image description here

私はprodを使用しているので、そのリンクをクリックしてこれを確認します。

enter image description here

これはログエントリの長いリストだと思います。この文脈で「ストリーム」が何を意味するのかわかりません。これらのエントリは何百もあります。そのため、タイムスタンプが最新のものを選択してクリックします。今私はこれを見ます:

enter image description here

私のゲートウェイログはすべてこのようになっているようです。 IE:どうやら空です。

だから、私はロギングを正しく設定していますか?私は正しい場所を探していますか?

9
Doug Hughes

私はこれを経験しました... CORSの有効化に関するAWSラムダドキュメントに隠されているのは、ラムダにCORSヘッダーを設定する必要があるという事実でした。だからここにそれを行う方法があります:

let payload = {
    statusCode: 400,
    body: JSON.stringify('body'),
    headers: {"Access-Control-Allow-Origin": "*"} // NEED this for API CORS access
};
callback(null, payload);

ヘッダーとともに有効なstatusCodeとbodyを返す必要があります。そうしないと、APIはラムダ応答をAPI応答に変換できません。

1
Ben Richards

aws-serverless-express でOPTIONS 500エラーが発生する場合、解決策は Swaggerテンプレート のOPTIONSメソッドにcontentHandling: CONVERT_TO_TEXTを追加することです。

これは、// {proxy +}を含むSwaggerテンプレートファイルです。パス

---
swagger: 2.0
info:
  title: AwsServerlessExpressApi
basePath: /prod
schemes:
- https
paths:
  /:
    x-Amazon-apigateway-any-method:
      produces:
      - application/json
      responses:
        200:
          description: 200 response
          schema:
            $ref: "#/definitions/Empty"
      x-Amazon-apigateway-integration:
        responses:
          default:
            statusCode: 200
        uri: arn:aws:apigateway:YOUR_AWS_REGION:lambda:path/2015-03-31/functions/arn:aws:lambda:YOUR_AWS_REGION:YOUR_ACCOUNT_ID:function:${stageVariables.ServerlessExpressLambdaFunctionName}/invocations
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
    options:
      consumes:
      - application/json
      produces:
      - application/json
      responses:
        200:
          description: 200 response
          schema:
            $ref: "#/definitions/Empty"
          headers:
            Access-Control-Allow-Origin:
              type: string
            Access-Control-Allow-Methods:
              type: string
            Access-Control-Allow-Headers:
              type: string
      x-Amazon-apigateway-integration:
        contentHandling: CONVERT_TO_TEXT
        responses:
          default:
            statusCode: 200
            responseParameters:
              method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
              method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
        passthroughBehavior: when_no_match
        requestTemplates:
          application/json: "{\"statusCode\": 200}"
        type: mock
  /{proxy+}:
    x-Amazon-apigateway-any-method:
      produces:
      - application/json
      parameters:
      - name: proxy
        in: path
        required: true
        type: string
      responses: {}
      x-Amazon-apigateway-integration:
        uri: arn:aws:apigateway:YOUR_AWS_REGION:lambda:path/2015-03-31/functions/arn:aws:lambda:YOUR_AWS_REGION:YOUR_ACCOUNT_ID:function:${stageVariables.ServerlessExpressLambdaFunctionName}/invocations
        httpMethod: POST
        type: aws_proxy
    options:
      consumes:
      - application/json
      produces:
      - application/json
      responses:
        200:
          description: 200 response
          schema:
            $ref: "#/definitions/Empty"
          headers:
            Access-Control-Allow-Origin:
              type: string
            Access-Control-Allow-Methods:
              type: string
            Access-Control-Allow-Headers:
              type: string
      x-Amazon-apigateway-integration:
        contentHandling: CONVERT_TO_TEXT
        responses:
          default:
            statusCode: 200
            responseParameters:
              method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
              method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
        passthroughBehavior: when_no_match
        requestTemplates:
          application/json: "{\"statusCode\": 200}"
        type: mock
x-Amazon-apigateway-binary-media-types:
  - '*/*'
definitions:
  Empty:
    type: object
    title: Empty Schema

詳細については、GitHubをご覧ください リクエストメソッドOPTIONS時の内部サーバーエラー

お役に立てれば!

1
iurii

@scopchanovと同様の問題があります。

AWS Lambda + API Gateway + Serverless Framework 1.42.3 + Express.jsプロジェクトで機能するものは次のとおりです。

  1. CORSを有効にする/ Expressからヘッダーを送信する必要があります。

    // AWS API Gateway CORS(OPTIONS)のサポートにバグがありますか? app.use(cors({credentials:true})); app.options( "*"、cors());

  2. しないでください API GatewayでCORSを有効にします。つまり、serverless.ymlでこれを行わないでください。

    • http:メソッド:ANYパス: '{proxy +}'#は{"メッセージ": "内部サーバーエラー"}を引き起こします#cors:true

cors: trueがないと、すべてのリクエストが正常に機能します。

cors: trueを使用すると、OPTIONSリクエストは{"message": "Internal server error"}で応答します(Lambda関数の機能に関係なく、これはAPI GatewayまたはバグのあるMOCK統合によって直接送信されるようです)。

0
Hendy Irawan

Cloudformationを使用してサーバーレスソリューションを作成するときにも同じ問題が発生しました。 CloudformationはAPIGateway + Lambdaを作成し、すべてが正常に見えます。ただし、OPTIONSリクエストは内部サーバーエラーを返していました。

API Gatewayにアクセスして、APIを手動で1回だけ公開する必要がありました。 (イベントはすでにprodステージに公開されていますが)その後、OPTIONSリクエストが機能しました。これで、cloudformationを使用して更新できます。

0
Baran Baygan