現在、React学習をしているところで、簡単なWebアプリを作ろうとしています。
そのアプリではAWS API Gateway経由でLambdaを実行してDynamoDBのデータを取得する部分があるのですが、npm startで実行してlocalhostからデバックしようとする際にCORSエラーが発生してしまったので、私が行った対応方法について記載します。
※この記事の続きとしてPOSTで引き続きCORSエラーになったので以下の記事を追加しました(21/12/16)
1. バックエンド構成
バックエンドですが、API Gateway -> Lambda -> dynamoDBのごくシンプルな構成となっております。
API GatewayのURLにGETでアクセスすると、dynamoDBからアイテムの一覧がjsonで取得できるようにしています。
API Gatewayはプロキシ統合として構築しています。
今回はサンプルとして以下の様なjsonデータを返すようにします。
[
{
"user_name": "guest"
"time": "2021/10/08 14:47:54"
},
{
"user_name": "guest"
"time": "2021/10/08 15:27:32"
},
.
.
.
]
2. エラーの内容
開発者ツールでエラー内容を見ると以下メッセージが表示されています。URLは事前に構築しているAWS API GatewayのURLになります。
Access to XMLHttpRequest at 'https://xxx.execute-api.xxxx.amazonaws.com/xxxx' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
3. CORSとは
Cross-Origin Resource Sharingの略で、コルス
と呼びます。日本語訳するとオリジン間リソース共有
と呼びます。
フロントとバックエンドが異なるサーバで動作している場合には、この設定をしていないと、フロントからAPIを叩いて、APIサーバーの値を取得したり、保存したりということが出来ません。
もう少し具体的にいうと、異なるドメイン間での通信は出来ない「same-origin policy」というルールがあるので、そのルールに従って設定する必要があるという事です。
4. CORSエラーの原因調査
今回はAWS APIGatewayで構築しているの、AWSのページに記載を確認してみます。
[簡単な説明]
クロスオリジンリソース共有 (CORS) エラーは、サーバーが CORS 標準で要求される HTTP ヘッダーを返さない場合に発生します。API Gateway REST API または HTTP API からの CORS エラーを解決するには、CORS 標準を満たすように API を再設定します
[解決方法]
以下の例は、「「Access-Control-Allow-Origin」ヘッダーが存在しません」という CORS エラーをトラブルシューティングする方法を示しています。なお、同様の手順を使用して、すべての CORS エラーをトラブルシューティングできます。例: 「メソッドは Access-Control-Allow-Methods ヘッダーでサポートされていません」というエラー、および「「Access-Control-Allow-Headers」ヘッダーが存在しません」というエラー。
注: 「「Access-Control-Allow-Headers」ヘッダーが存在しません」というエラーは、次のいずれかの理由で発生する可能性があります。
①API が、必要な CORS ヘッダーを返す OPTIONS メソッドで設定されていない。
②必要な CORS ヘッダーを返すように別のメソッド型 (GET、PUT、POST など) が設定されていない。
③プロキシ統合または非プロキシ統合を持つ API が、必要な CORS ヘッダーを返すように設定されていない。
④プライベート REST API の場合、不正な呼び出し URL が呼び出されるか、トラフィックがインターフェイス仮想プライベートクラウド (VPC) エンドポイントにルーティングされていない。
上のエラーの解決方法でいうろ②と③あたりの対応をAPI Gatewayの裏側でRerutnコードを返しているLambdaに設定する必要がありそうです。
5. 対応方法
という事で、Lambda側のRerutnコードに追加してあげます。
これまでは以下の様なコードでReturnしていました。
def return_success(data):
return {
'statusCode': 200,
'body': json.dumps(data)
}
「Access-Control-Allow-Headers」ヘッダーが存在しないのでCORSエラーになっているので追加してあげます。
「”Access-Control-Allow-Origin”: “*”」として全てのドメインからアクセスを許可していますが、ここら辺は適宜変更してください。
また「”Access-Control-Allow-Methods”」についても利用するメソッドだけ記載するほうが良いですね。
def return_success(data):
return {
'statusCode': 200,
'headers': {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "POST,GET,PUT,DELETE",
"Access-Control-Allow-Headers": "Content-Type"
},
'body': json.dumps(data)
}
6. 対応結果
Lambda側のコードを修正して、LambdaにDeployしなおすと、CORSエラーが解消されるはずです。
7. まとめ
Reactを学習していてCORSエラーの対応にぶつかりましたが、以前にVue.js使っていた際も同じ問題にぶつかっていたことを思い出しました。
セキュリティ部分なので理解したうえで実施することが大事かと思います。(本番環境の場合には特に)
AWSを効率的に学習する方法
私が効率的にAWSを学習するために実施した方法は以下の通りです。
①最初に書籍(ハンズオンができる)を購入、座学でAWSの基礎を学習
②AWS資格試験を取得ための学習
※私の場合は①と②を合わせて2か月でソリューションアーキテクトを取得できました。
①AWS基礎学習
最初に購入した書籍は「Amazon Web Services 基礎からのネットワーク&サーバー構築」です。
Amazon Web Services 基礎からのネットワーク&サーバー構築
この本では、AWSの基本サービスを利用したハンズオンを通じて、AWSの基礎を学習することができます。
また、タイトル通りAWSのネットワークやインフラに関しても網羅しているため、もともとインフラ系の技術者ではない人たちにとっても分かりやすい内容だと思います。
とりあえずAWS上にサーバーを設定して開発を行うための準備までするには最良の一冊です。
Amazon Web Services 基礎からのネットワーク&サーバー構築
②AWS資格取得
AWSの基礎をある程度学習することができたら、次はAWS資格を取得しましょう。まずはAWSソリューションアーキテクトを目指しましょう。
資格勉強のための問題集をひたすら解きながら、AWSの知識を積み重ねて習得していきましょう!
苦行ではありますが、この問題集を3周ほどすればAWS用語や構成に関しても習得できているはずです。
今回は以上となります。
コメント