스프링 부트로 프로젝트를 하면서 API를 만들어 포스트맨 확인 후 넘겨드렸는데 CORS 오류가 발생했다는 얘기를 전해들었다. 해당 오류는 SOP 정책을 위반했을 때 발생하는 오류이며 SOP 정책은 다음과 같다.

 

SOP(Same Origin Policy) 정책

같은 호스트, 같은 포트, 같은 프로토콜에서만 요청을 주고받을 수 있는 보안 정책

스프링 부트에서 아무런 설정을 적용하지 않으면 위 SOP 정책을 그대로 따르게 된다고 한다.

 

그럼 SOP 정책을 어떻게 변경할 수 있을까?

해답은 CORS(Cross-Origin Resource Sharing)을 이용하면 된다고 한다.

CORS는 같은 호스트, 같은 포트, 같은 프로토콜이 아니더라도 요청을 주고 받을 수 있도록 해준다.

 

CORS를 적용하는 법

1. CORS 적용이 필요한 컨트롤러 위에 @CrossOrigin("*") 애노테이션을 추가한다.

2. WebMvcConfigurer 인터페이스를 상속받아서 설정한다.(스프링 시큐리티 사용 안할 시)

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("http://localhost:3000");
    }

3. 스프링 시큐리티 설정 관련 config 파일에 아래 내용 추가 (스프링 시큐리티 사용할 시)

@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity.cors().configurationSource(request -> {
        var cors = new CorsConfiguration();
        //허용할 주소
        cors.setAllowedOrigins(List.of("http://localhost:3000")); 
        //허용할 http 메소드
        cors.setAllowedMethods(List.of("GET","POST", "PUT", "DELETE", "OPTIONS"));
        //허용할 header
        cors.setAllowedHeaders(List.of("*"));
        return cors;
    });

 

필자는 스프링 시큐리티를 사용하고 있어서 3번으로 해결했다.

 

참고 사이트

https://velog.io/@minchae75/Spring-boot-CORS-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0

 

 

 

Jwt 파싱할 때 발생한 오류다.

구글링해서 알아보니 parsing한 secert key 값이 원래 로컬에 저장된 secret key값과 달라서 발생하는 오류라고 한다.

 

먼저 오류 발생했던 초기 코드는 아래와 같다.

Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody().getSubject();

 

이후 구글링을 통해 다수의 사람들이 해결하던 .getBytes()를 추가하는 방식으로 수정해봤으나 오류가 해결되지 않았다.

.getBytes()를 통해 바이트 형식으로 키 값을 다뤄 key 값이 토큰에 들어가거나 파싱되는 순간에 변경이 되는 걸 방지한다는 디버깅 방식이었다.

Jwts.parser().setSigningKey(secretKey.getBytes()).parseClaimsJws(token).getBody().getSubject();

 

위 방식으로도 해결이 안된 이후로 몇 시간 동안 이 코드만 디버깅을 시도했었다.

구글링해도 자료가 많지 않아 난항을 겪고 있던 와중에 한 중국인이 올린 코드를 보게 됐고 그 분 방식처럼 아예 parsing하는 함수를 따로 분리하면서 문법도 바꿔 작성하니 오류가 해결됐다...

 

참고한 글은 아래 참고 사이트에 링크 남겼고 내가 작성한 오류 해결 코드는 아래와 같다.

 /**
     * Access 토큰 파싱
     * @param jwt
     * @return
     */
    public Claims parseJwt(String jwt) {
        Claims claims = Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();

        return claims;
    }
    
    Claims claims = parseJwt(token);
    String s=claims.getSubject();

 

 

 

참고 사이트 

https://github.com/jwtk/jjwt/issues/177

EC2서버에서 스프링 부트 프로젝트를 돌리는데 계속 빌드를 하다 멈추는 일이 발생했다.

디스크 메모리 용량을 확인해보니 아직 한참 남아서 cpu 사용량을 확인해보니 RAM이 딸려서 발생하는 문제인 것 같았다.

알아보니 t2.micro의 램이 1GB밖에 안돼서 현재 서버에서 스프링 부트 빌드만 해도 터지는 것 같았다.

이전 스프링 부트 프로젝트를 할 때는 램이 모잘라서 터지진 않았는데

이번 스프링 부트 프로젝트는 사용하는 기술들이 많아 몸집이 상당히 커져서 계속 터지는 것 같다.

 

다행히 리눅스에서는 SWAP 메모리를 지정할 수 있어서 RAM이 부족할 때 HDD의 일정 공간을 마치 RAM처럼 사용할 수 있었다. 속도가 좀 느리긴 하지만 그래도 돌아가는게 어디인가

(실무에서는 좋은 해결 방법이 아닌 것 같은데 애초에 실무에서 쓰이는 서버라면 RAM이 1GB이지 않을 것 같다ㅎㅎ)

 

램이 2GB이하일 땐 보통 RAM 용량의 2배를 SWAP 메모리로 잡는데 ec2는 1GB로 SWAP 메모리는 2GB로 잡아서 설정할 예정이다. 이때 주의해야되는게 SWAP 메모리의 공간이 최소 32MB는 돼야한다고 한다.

 

free 명령어를 통해 메모리(램)과 SWAP 메모리를 확인해 볼 수 있다.

현재 이렇게 SWAP 메모리 할당이 안돼있는 상태이다.

이제 SWAP 메모리를 할당해보자.

sudo dd if=/dev/zero of=/swapfile bs=128M count=16   //2GB정도 공간 할당
sudo chmod 600 /swapfile    //swap 파일 권한 업데이트
sudo mkswap /swapfile    //linux swap 영역 설정
sudo swapon /swapfile    //swap space에 swap file 추가
sudo swapon -s    //위 명령어들 성공 확인

다음으로 /etc/fstab 파일을 편집하여 부팅 시 swap 파일을 활성화 해줘야 한다.

$ sudo vi /etc/fstab

제일 마지막에 아래 내용을 추가해준다.

/swapfile swap swap defaults 0 0

 

다시 free 명령어로 확인해보자.

 

참고사이트

https://aws.amazon.com/ko/premiumsupport/knowledge-center/ec2-memory-swap-file/
https://sundries-in-myidea.tistory.com/102

https://incomeplus.tistory.com/284?category=868671

ec2 서버에 프로젝트 코드를 정상적으로 옮기는 것 까지 성공했다면

이젠 해당 코드들을 빌드하고 무중단 서비스를 실행하고 중단해보자.

 

스프링 부트 프로젝트가 있는 이전 폴더로 이동합니다.

 

맨 처음 빌드시 permission denied가 뜨니 먼저 권한 설정부터 해줍니다.

chmod -R 777 프로젝트있는폴더명/

이후 프로젝트 폴더로 이동해줍니다.

 

스프링 부트 프로젝트 빌드 

./gradlew clean build

스프링 부트 무중단 서비스 시작

각자 맞는 실행파일 이름은 build/libs 폴더에 들어가서 확인할 수 있다.

nohup java -jar build/libs/{각자맞는이름}-0.0.1-SNAPSHOT.jar &

스프링 부트 무중단 서비스 종료

ps -ef | grep {각자맞는이름}-0.0.1-SNAPSHOT.jar
=>종료시킬 스프링 부트 pid 확인
sudo kill -9 확인한pid
=>무중단 스프링 부트 중지

Amazon RDS(Relational Database Service)란?

분산 관계형 데이터베이스 서버 인스턴스로서 관계형 데이터베이스의 설치, 관리, 업데이트를 알아서 해준다.

따라서, RDS를 통해 관계형 데이터베이스를 손쉽게 사용, 관리할 수 있고 스토리지 확장 같은 기능들을 활용할 수 있다.

프리티어 계정이라면 aws에서 직접 운용하는 Aurora는 사용할 수 없고 Microsoft SQL, Oracle, MySQL, Aurora, Maria DB 중에서 하나를 택해서 임대 받으면 된다.


1. RDS 데이터베이스 생성받기

검색창에서 RDS 검색 후 데이터베이스 클릭

필자는 이미 임대 받은 RDS가 있어서 저렇게 뜨지만 원래는 목록이 비어있다.

데이터베이스 생성 클릭

원하는 데이터베이스 종류 선택

Aurora는 프리티어 무료 계정으로 사용할 수 없다.

버전을 확인할 수도 있고 변경을 원할 시 변경도 가능하다.

무료로 사용할 예정이므로 프리 티어를 선택한다.

데이터베이스 이름, 마스터 이름, 비밀번호를 설정한다.

이후 워크벤치, 데이터그립등을 활용하여 데이터베이스에 접근할 때 필요한 정보이므로 신중하게 설정해야한다.

과금을 막기 위해 범용 SSD 스토리지 유형 선택, 자동 조정 활성화 체크를 해제한다.

외부에서도 데이터베이스에 접근할 수 있도록 퍼블릭 엑세스를 예로 바꿔준다.

aws의 모든 인스턴스들은 내부/외부 상호작용을 위해 vpc 설정을하는데 필자는 기본 vpc를 선택했다.

외부에서 DB에 접근할 때 인증 옵션을 선택해야한다.

현업이 아니고 사이드 프로젝트용으로 사용할 것이기 때문에 간단하게 암호 인증으로 선택했다.

이후 데이터 베이스 생성 버튼 클릭하면 데이터베이스 인스턴스가 생성되며 RDS 데이터베이스 탭에서 확인가능하다.

 

2. RDS 파라미터 그룹 변경

Time Zone, Character Set, Max Connection 파라미터 값을 변경해줘야한다.

RDS에 들어가서 파라미터 탭->파라미터 그룹 생성 클릭

그룹 이름과 설명을 적어준 뒤 생성 버튼 클릭

 

아래 사진들의 왼쪽 이름을 검색 후 오른쪽과 같이 설정 변경

time_zone

charcter_set

한글과 이모지 지원

max_connection

 

 

최종 변경 사항 저장 클릭

다시 RDS 데이터베이스 탭으로 이동하여 해당 데이터베이스를 클릭한 후 수정 클릭

추가 구성에서 방금 생성한 파라미터 그룹으로 설정 후 초기 설정이므로 즉시 적용 클릭

예시로 만들던 파라미터 그룹과 이름이 다른건 이전 파라미터 그룹을 설정한 것으로 신경안쓰셔도 됩니다.

 

3. 보안그룹 설정

RDS 데이터베이스 탭에서 원하는 인스턴스의 이름 클릭

연결&보안에서 vpc 보안 그룹 밑 이름 클릭

 

인바운드 규칙 탭에서 인바운드 규칙 편집 클릭

외부에서 접속하려는 ip 추가(로컬에서 접근시 네이버에서 내 ip 주소치면 ip주소 확인 가능)

이때  ip주소 뒤에 /32를 넣어줘야된다.

ec2 보안 그룹 ID를 복사해서 넣어줘도 된다. 

다 추가했으면 규칙 저장

 

이제 초기 설정은 다 끝났다. 

 

이후 원하는 프로그램을 써서 데이터베이스에 접근하면 된다.

필자는 주로 데이터그립을 사용하며 데이터그립을 활용해 연결하는 방법은 아래 게시물을 참고하면 된다.

https://cofls6581.tistory.com/60

 

Datagrip으로 MySQL 외부에서 접속하기

Datagrip이란? 외부 접속위한 DB 개발과 관리를 용이하게 해주는 GUI 개발 툴 Datagrip 다운 www.jetbrains.com/ko-kr/datagrip/download/#section=windows 학생 인증 후 무료 라이센스 pack 다운로드 new project..

cofls6581.tistory.com

 

참고 사이트

https://overcome-the-limits.tistory.com/294

https://bcp0109.tistory.com/357?category=1073811

https://8iggy.tistory.com/71

https://brunch.co.kr/@topasvga/696

스프링 부트에서 Redis 서버를 연결해서 작동하는 로직이 있는데 코드를 작성한 후 관련 api를 실행시켜보니 ERR Client sent AUTH, but no password is set라는 에러로그가 출력됐다.

Redis 서버에 비밀번호 설정을 안해줬거나 설정해줬는데 yml과 같은 Redis 서버 연결관련 설정 파일에 비밀번호를 제대로 적지 않아줘서 생기는 오류이다.

분명 초반에 깔 때 비밀번호를 설정해주고 확인까지 했었는데 비밀번호가 날라가있었다. 
+원인을 알았다. 집에서 사용하는 IP가 고정적인 IP가 아니여서 가끔씩 IP가 바뀌는데 IP가 바뀌면 redis 설정을 다시 해줘야하는 것 같다.

 

참고용 내 redis 서버 yml 설정 파일 코드는 아래와 같다.

spring:
  redis:
    host: localhost
    port: 6379
    password: '설정한비밀번호'
    lettuce:
      pool:
        max-active: 10
        max-idle: 10
        min-idle: 2

 

비밀번호를 설정해주지 않았거나 기억이 안난다면 아래를 따라오면 된다.

 

비밀번호 확인

 

redis-cli 실행

config get requirepass

 

"requirepass"

""

뜨면 비밀번호 설정이 안된 상태로 설정해줘야 한다.

 

비밀번호 설정법

 

redis-cli 실행

config set requirepass 비밀번호

이후 아래 코드를 치면

auth 설정한비밀번호 

config get requirepass

"requirepass"

"설정한비밀번호"

정상적으로 비밀번호가 변경됐음을 확인할 수 있다.

 

 

+ Recent posts