이 포스팅은 이전에 했던 API 서버와 UI를 연동하는 과정에서의 이슈를 해결...? 하는 과정이다.
2022.02.15 - [웹] - Spring + Kotlin API Server 만들기 (1) : 프로젝트 시작, MVC 패턴
2022.02.16 - [웹] - React UI 만들기 (1) : 환경 세팅
Security 문제
react application을 배포하고 처음 당한 문제점이다. react가 amplify로 배포되면서 자동으로 ssl이 붙어 ㅁ axio 요청이 https로 나가게 된다. 여기서 기존 API 서버는 ssl 설정을 하지 않아 http이기 때문에 https에서 http로 요청이 간다고 에러를 뱉어버린다.
- 해결 방법
- Cloudfront를 붙인다. (Cloudfront를 붙이면 ACM에서 알아서 https 인증을 해준다.)
AWS Cloudfront
기존에 있던 aws elastic beanstalk에 aws cloudfront 붙이는 방법은 다음과 같다.
1. 배포생성 클릭
2. 원본 도메인에서 elastic beanstalk이 만든 load balancer 선택
2. 뷰어 설정
3. 캐시 설정
*** 원래 여기서 TTL을 넣어 줘야하는데 저걸 넣는 순간 Sping security 설정을 해줘야 해서 그냥 캐시 ttl 0 을 줘서 날렸습니다!!
*** 캐시 안날리면 POST로 데이터 변경 해도 GET요청에서 캐시 된 데이터가 나와서 사용자는 데이터 업데이트를 못봄
-response header에 뭐 해줘야 한다는데 아직 공부를 못했어요...)
4. SSL 인증서 요청
5. 퍼블릭 인증서 요청 선택
6. 도메인 작성
7. SSL 인증서 발급 확인
8. cloudfront에서 인증서 선택후 생성
이제 기존에 만들었던 도메인에 접속하면 https로 인증이 돼 있는 걸 확인 할 수 있다. 하지만 여전히 문제는 남아있다.
CORS
SSL까지 문제를 해결 했지만 여전히 외부 도메인에 요청을 걸었다고 axios가 에러를 열심히 뱉어낸다. 이를 해결하기 위해 서버 쪽에 CORS설정을 해줘야 한다. 다음과 같은 코드를 API 서버에 추가한다.
- GlobalConfig.kt
package com.studuy.study.config
import org.springframework.context.annotation.Configuration
import org.springframework.http.CacheControl
import org.springframework.http.HttpMethod
import org.springframework.web.servlet.config.annotation.CorsRegistry
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer
@Configuration
class GlobalConfig : WebMvcConfigurer{
override
fun addCorsMappings(registry: CorsRegistry) {
registry.addMapping("/**")
.allowedOrigins("<https://device-ui.lachani.com>", "<http://device-ui.lachani.com>")
.allowedMethods(
HttpMethod.GET.name,
HttpMethod.POST.name,
HttpMethod.PUT.name,
HttpMethod.DELETE.name,
HttpMethod.PATCH.name
)
}
}
- 설명
- allowedOrigins
- 요청이 들어왔을때 허용된 도메인을 의미한다.
- 개발할 땐 http://localhost:3000을 적어주자(react url)
- 배포할 땐 ui서버의 도메인을 적어서 ui서버에서 요청이 들어왔을 때 허용하게 해주자.
- 요청이 들어왔을때 허용된 도메인을 의미한다.
- allowedMethods
- 허용된 method를 의미한다.
- 기본적인 API니까 적당히 허용해주자.
- 허용된 method를 의미한다.
- allowedOrigins
추가
추가적으로 cloudfront의 ttl이 0이 아닌 이상 서버 배포가 다시 이뤄져도 Cloudfront를 cache에 있는 데이터를 주기 때문에 배포를 하면 invalidate cache를 cloudfront에 날려서 cache를 초기화 해줘야 한다.
이를 github action workflow에 다음과 같이 넣어주자
name: Deploy Device API Server
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout source code
uses: actions/checkout@v2
- name: Set up JDK 11
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '11'
cache: 'gradle'
- name: Add permission for gradlew
run: chmod +x ./gradlew
shell: bash
- name: Build with Gradle
run: ./gradlew clean build -x=jar
shell: bash
- name: time for Versioning
uses: 1466587594/get-current-time@v2
id: current-time
with:
format: YYYY-MM-DDTHH-mm-ss
utcOffset: "+09:00"
- name: Set artifact
run: echo "artifact=$(ls ./build/libs)" >> $GITHUB_ENV
- name: Deploy
uses: einaregilsson/beanstalk-deploy@v20
with:
aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
application_name: spring_kotlin_api
environment_name: Springkotlinapi-env
version_label: main-${{ steps.current-time.outputs.formattedTime }}
region: ap-northeast-2
deployment_package: ./build/libs/${{env.artifact}}
wait_for_environment_recovery: 30
##추가
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Invalidate CloudFront Cache
run: aws cloudfront create-invalidation --distribution-id ${{secrets.CLOUD_FRONT_ID}} --paths "/*"
그러면 웹페이지가 다음과 같이 정상 작동 한다.
'웹' 카테고리의 다른 글
AWS Simple Queue Service 맛보기 (0) | 2022.02.17 |
---|---|
python request로 API 호출 (0) | 2022.02.17 |
React UI 만들기 (3) : AWS Amplify로 배포 (0) | 2022.02.17 |
React UI 만들기 (2) : Component, MainContainer 만들기 (0) | 2022.02.17 |
React UI 만들기 (1) : 환경 세팅 (0) | 2022.02.16 |