LoginSignup
10
10

More than 3 years have passed since last update.

【APIGateway・Lambda】AxiosでAPIを叩いた時にCORS設定でハマった

Last updated at Posted at 2021-01-23

ReactからAxiosでLambdaで作ったAPIへリクエストした時に、CORSの設定でハマったのでメモしておきます。

症状

curlではレスポンスがAPIから帰ってくるが、AxiosでReact側からリクエストをすると、下記のエラーメッセージが返ってくる。

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

原因

API GatewayでCORSが有効化されていない。
Lambda関数が必要なヘッダー情報を返していない。

CORS(Cross-origin resource sharing) とは?

  • ブラウザのセキュリティ機能。
  • ブラウザからのHTTPリクエストを制限する。

ざっくりいうとこのセキュリティ機能のせいで、ReactからLambdaのAPIを叩けない。
具体的に言うと、プレフライトリクエストがアクセスコントロールチェックをパスしていない。

プレフライトリクエストについて
簡単言うと、OPTIONSメソッドでAPIへの疎通確認するリクエスト。
詳しくは、https://developer.mozilla.org/ja/docs/Web/HTTP/CORS#preflighted_requests

解決法

1. APIGatewayでCORSを有効化

⑴ AWSにログイン。APIGatewayのコンソール画面からAPIを選ぶ。

⑵ 「アクション」 > 「CORSの有効化」を選択。

スクリーンショット 2021-01-23 13.29.10.png

⑶ ヘッダーの設定

  • メソッド:OPTIONSにチェックが入ってることを確認。(preflightアクセスで使う。OPTIONSメソッドでAPIへの疎通確認。)
  • Access-Control-Allow-Headersが、デフォルトは'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'だけど、オープンな場合認証情報は必要ないので'Content-Type,X-Amz-Date'に設定。

スクリーンショット 2021-01-23 13.29.33 2.png

設定が終わったら「CORS を有効にして既存の CORS ヘッダーを置換」ボタンをクリック。

⑷ APIのデプロイをクリック

「APIのデプロイ」をクリック。デプロイしないと設定が反映されない。

スクリーンショット 2021-01-23 13.31.11.png

2. Lambdaで必要なヘッダー情報を返す。

下ようにヘッダー情報を返すように関数を修正。デプロイする。

import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        'headers': {
            'Access-Control-Allow-Headers': 'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*', // アクセス元を限定するときは 'https://www.example.com'と指定。
            'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
        },
        'body': json.dumps('Hello from Lambda!')
    }

3. Reactからリクエストを投げる

import axios from 'axios';

axios({
  method: 'post',
  url:'https://xxx.execute-api.ap-northeast-1.amazonaws.com/default/your-api',
  data: {
    line_count: lineCount,
    text: finalText,
  },
})
.then(results => {
  console.log(results);
)
.catch(results => {
  console.log(results);
});

最後に

これでレスポンスが返ってくるようになりました。
もし、これでもまだ返ってこない場合は、LambdaのCloudWatchのログを見てみるか、Testing CORS - Amazon API Gateway を参考にCORSテストをしてみてください。

参考

APIGatewayでCORSを有効化
https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors-console.html
LambdaでCORSを有効化
https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-cors.html

10
10
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
10