https://github.com/kyopark2014/aws-routable-cloudfront
It shows how to escape cross-origin issues for web client and API server using CloudFront routing.
https://github.com/kyopark2014/aws-routable-cloudfront
aws aws-s3 cdk cloudfront cloudfront-distribution javascript s3
Last synced: 4 months ago
JSON representation
It shows how to escape cross-origin issues for web client and API server using CloudFront routing.
- Host: GitHub
- URL: https://github.com/kyopark2014/aws-routable-cloudfront
- Owner: kyopark2014
- Created: 2022-06-01T11:55:18.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2023-01-27T01:35:56.000Z (over 3 years ago)
- Last Synced: 2025-04-12T19:40:12.464Z (about 1 year ago)
- Topics: aws, aws-s3, cdk, cloudfront, cloudfront-distribution, javascript, s3
- Language: TypeScript
- Homepage:
- Size: 160 KB
- Stars: 4
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# AWS CloudFront의 URL Routing을 이용한 Web Client 및 API Server 구현
여기서는 CliendFront의 URL Routing을 이용하여 Web Client와 API Server를 구현하고자 합니다. Web Client는 Amazon S3에 html과 javascript과 같은 respource들로 구성되며, javascript에서 '/status'와 같은 API를 호출하면, Amazon API Gateway를 통해 lambda를 호출하는 구조를 되어 있습니다. 또한, 쉽고 편리하게 인프라를 구축하기 위하여 [AWS CDK](https://github.com/kyopark2014/technical-summary/blob/main/cdk-introduction.md)를 이용합니다.
전체적인 Architecture는 아래와 같습니다. 사용자가 Amazon CloudFront를 이용해 web page에 접속 할 수 있습니다. 또한 restful api로 접속시에는 api의 method 이름을 이용하여 적절한 경로로 Routing 할 수 있습니다. 여기에서는 status Method를 가지고 '/status'라는 URL을 가지므로, Amazon API Gateway로 routing 되어지는데, 이때 API Gateway와 연결된 Lambda를 통해 원하는 동작을 요청 할 수 있습니다.

## CORS 에러
브라우저는 HTTP 보안을 위해 리소스의 origin (domain, scheme, port)을 확인하여 원래 사이트의 origin과 다른 경우(cross-origin)에 접속을 제한합니다.

자신의 origin과 다른 리소스를 허용하려면 [Cross-Origin Resource Sharing(CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)를 적용하여야 하는데, 브라우저는 preflight request(OPTIONS)를 보내서 서버로부터 "approval"을 받으면, actual request를 보낼 수 있습니다. 여기서 OPTIONS 해더에 origin 헤더가 반드시 포함되어야 합니다.

그런데, [Chrome과 같은 브라우저에서 request에 origin을 허용하지 않은 경우](https://stackoverflow.com/questions/11182712/refused-to-set-unsafe-header-origin-when-using-xmlhttprequest-of-google-chrome)가 있어서, API Gateway에서 CORS 설정을 하더라도, CORS 에러로 request가 실패 할 수 있습니다.
따라서, 여기에서는 원천적으로 crosss-origin 이슈가 발생하지 않도록, contents(html, css, js)와 같은 리소스가 같은 origin을 사용할 수 있도록 CloudFront를 사용하는 방법을 설명합니다.
## CloudFront를 이용한 cross-origin 이슈 해결 방법
아래와 같이 CloudFront를 이용하여 '/status'로 시작하는 모든 request는 API Gateway를 통해 제공하고, 나머지 request는 S3로 routing 되도록 할 수 있습니다. 상세한 것은 [CDK Cloudfront](https://github.com/kyopark2014/aws-routable-cloudfront/tree/main/cdk-cloudfront)를 참고 하시기 바랍니다.
```java
const distribution = new cloudFront.Distribution(this, 'cloudfront', {
defaultBehavior: {
origin: new origins.S3Origin(s3Bucket),
allowedMethods: cloudFront.AllowedMethods.ALLOW_ALL,
cachePolicy: cloudFront.CachePolicy.CACHING_DISABLED,
viewerProtocolPolicy: cloudFront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
},
priceClass: cloudFront.PriceClass.PRICE_CLASS_200,
});
distribution.addBehavior("/status", new origins.RestApiOrigin(apigw), {
cachePolicy: cloudFront.CachePolicy.CACHING_DISABLED,
originRequestPolicy: myOriginRequestPolicy,
viewerProtocolPolicy: cloudFront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
});
```
이렇게 할 경우에 아래와 같이 CloudFront에는 2개의 origin이 등록이 되는데, '/status' API의 경우는 api gateway로 전달되어 처리되고, 나머지는 S3로 라우팅 됩니다.

## CDK로 인프라 설치하기
git repository에서 소스를 다운로드 합니다.
```c
$ git clone https://github.com/kyopark2014/aws-routable-cloudfront
```
아래의 [AWS CDK](https://github.com/kyopark2014/technical-summary/blob/main/cdk-introduction.md)명령어를 이용하여 인프라를 생성합니다.
```c
$ cd cdk-cloudfront
$ cd cdk synth
$ cd deploy
```
인프라를 생성하는 방법은 [AWS CDK 인프라 생성하기](https://github.com/kyopark2014/aws-routable-cloudfront/tree/main/cdk-cloudfront)에서 상세히 설명하고 있습니다.
인프라 삭제시는 아래 명령어를 사용합니다.
```c
$ cdk destroy
```
## 실행 결과
### Postman에서 '/status' API 호출시
'/status'는 lambda-for-status로 routing되고 있으므로 아래와 같이 Lambda가 실행되는 것을 확인 할 수 있습니다.

### 브라우저(Chrome)에서 "status.html"을 호출시
html 내부의 request.js가 실행되면서, '/status' API를 호출하게 됩니다.
- "status.html"을 로딩 후 아래와 같이 [RUN]을 선택합니다. 여기서 "status.html"은 S3에 저장되어 있고, CloudFront를 통해 로딩됩니다.

- [RUN] 버튼을 선택하면 "status.html"에서 지정한 "request.js"가 실행되는데, 이때 "lambda-for-status"를 호출하여 응답을 받고, 이것을 아래와 같이 화면에 "response"로 표시하고 있습니다.

## Reference
[AWS CDK — A Beginner’s Guide with Examples](https://enlear.academy/aws-cdk-a-beginners-guide-with-examples-424c600ac409)
[aws-cdk-changelogs-demo](https://github.com/aws-samples/aws-cdk-changelogs-demo)
[CloudFront to S3 and API Gateway](https://serverlessland.com/patterns/cloudfront-s3-lambda-cdk)
[CORS란 무엇인가?](https://hannut91.github.io/blogs/infra/cors)
[Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)