'프로그래밍/SpringBoot' 카테고리의 글 목록 :: 잡다한 프로그래밍
반응형

1. Transaction에서 rollback이 되지않는 경우는?

- checked exception은 트랜잭션에서 롤백되지않는다. (명시적인 예외처리가 필요한 것, try catch해야하는것 들)

- unchecked exception은 롤백대상 (예외처리를 하지 않아도 IDE에서 에러 뱉지 않음, Runtime Exception...)

 

2. checked exception 경우에도 rollback을 하고싶으면?

만약 B에서 에러가 발생했을때 A를 rollback시키고 싶다면? 이럴때 transaction을 이용한다

하지만 B의 exception이 checked exception이라면?

@Transactional
public void test() {
    A();
    B();
}

만약 아래처럼 try catch를 이용하면 에러를 catch에서 처리했기 때문에, rollback이 발생하지 않는다.

@Transactional
public void test() {
    A();
    try {
    	B(); // checked exception을 발생시키는 부분
    } catch {
    
    }
}

 

- @Transcational 어노테이션에 rollbackFor라는 옵션을 이용한다

해당 에러는 throw하고, rollbackFor옵션을 사용하면 checked exception도 확인할 수 있게 된다.

@Transactional(rollbackFor = {Exception.class})
public void test() {
    A();
    B(); // checked exception을 발생시키는 부분에서는 error throw
}

 

- checked 예외를 unchecked 예외로 변경하여 throw한다

public void B() {
    try {
    
    }catch(Exception e) {
    	throw new RuntimeException("예외");
    }
}


@Transactional
public void test() {
    A();
    B(); // unchecked exception으로 바꿈
}

 

3. 아래와 같은 경우에는 롤백이 일어날까 일어나지 않을까?

	// ATest 클래스
    @Transactional
    public void A() {
        try {
            test.B();
        } catch (RuntimeException e) {
            System.out.println("예외 처리");
        }
    }
    
    
    // BTest클래스
    @Transactional
    public void B() {
        //로직
        mapper.save();
        throw new RuntimeException("예외"); // unchecked exception
    }

 

해당 코드는 다음과 같이 동작한다.

1. A클래스의 트랜잭션이 실행된다.

2. B메소드가 실행되면서 1번의 트랜잭션에 참여한다 (기본 propagation 속성이 PROPAGATION_REQUIRED)

3. save를 실행하는 부분의 처리가 끝나고 트랜잭션의 완료처리 (completion)을 진행함

4. checked Exception이 일어나면서 트랜잭션이 완료처리 됨

5. checked Exception때문에 해당 트랜잭션을 롤백 규칙을 적용(기본 규칙적용), 해당 메소드에서 바로 롤백하지않고 rollback mark를 함 (해당 마크는 전역으로 관리함)

6. A의 로직 수행 > 1번에서 생성된 트랜잭션의 완료처리가 진행, 이때 rollback mark를 확인해서 값이 true라면 rollback진행

따라서 이경우에는 롤백되어버린다

 

해당 propagation 옵션을 변경할경우 해당 rollback mark 문제를 해결할 수 있다

 

PROPAGATION_REQUIRES_NEW 사용시 매번 새로운 트랜잭션 생성

- A와 B가 각각 트랜잭션을 생성하고, 매 번 commit하므로 서로의 rollback에 영향을 미치지 않음

하지만 오버헤드 발생할 수 있음 (매번 새로운 커넥션 생성)

반응형
반응형

JWT 사용시 csrf.disable()를 한다.

Cross-Site Request Forgery

이용자가 의도하지 않은 요청을 통한 공격을 의미한다.

즉, CSRF 공격이란, 인터넷 사용자(희생자)가 자신의 의지와는 무관하게 공격자가 의도한 행위(등록, 수정, 삭제 등)를 특정 웹사이트에 요청하도록 만드는 공격이다.

 

- session, cookie를 이용하는 경우, 서버에서 사용자가 올바른지 검증하게 된다. 서버에서 검증을 진행하다보니 의도하지않은 공격이 있는지 확인하는 절차가 필요하지만,

JWT의 경우 토큰값에 정보들이 들어있어 서버에서 별다른 검증이 필요하지않으므로 csrf를 disable해도 무방하다.

 

- spring security에서도 권장함

반응형
반응형

1. HTTPS란

  • HTTP는 인터넷에서 웹 서버와 사용자 브라우저간 문서를 전송하기 위한 통신 규약이다. HTTP는 정보를 텍스트로 주고받기 때문에 누군가가 네트워크 이를 가로챈다면 정보를 확인할 수 있어서 보안에 취약하다 HTTPS는 이를 암호화하여 보안상의 문제를 해결해주는 프로토콜이다
  • HTTPS는 새로운 프로토콜이 아닌 HTTP와 통신을 하는 소켓 부분을 SSL이나 TSL로 대체하는 것 즉 사용자는 SSL과 통신하여 암호화된 정보를 주고받는다.
  • HTTPS는 공개키 암호화 방식을 사용한다. 공개키 암호화 방식에는 비밀키와 공개키가 존재하는데 비밀키는 서버 쪽에 가지고 있으며 공개되어서는 안 되고, 공개키는 누구에게나 공개되어도 괜찮은 키이다. 먼저 클라이언트는 공개키를 통해 텍스트를 암호화하고 이는 비밀키로만 복호화할 수 있다 따라서 다른 사람이 정보를 가로채더라도 비밀키만 안전하다면 괜찮은 방식이다.

2. SpringBoot에 HTTPS 적용하기

 

#1) 사전준비

  • 스프링 부트 2.2.5 RELEASE, Dependency로 spring Web사용
  • Maven 사용 (Gradle사용 가능)
  • JAVA 1.8, 내장 톰캣 9 사용

 

#2) JAVA를 이용한 인증서 만들기

Intellij 터미널에서 다음과 같이 keystore.p12라는 키를 만든다 입력해야 할 이름, 도시 등 정보는 임의로 입력한다. 인증받은 키가 아니고 로컬에서 확인하는 용도 이므로 자유롭게 입력한다. 만약 인증된 키를 사용할 경우 값을 지불하고 이용해야 한다.

keytool -genkey -alias spring -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 4000

 

#3) application.properties 추가

키가 만들어졌다면 다음과 같은 내용을 추가한다

server.ssl.key-store= keystore.p12
server.ssl.key-store-password= 본인이 입력한 패스워드
server.ssl.key-store-type= PKCS12
server.ssl.key-alias= spring

#4) 프로젝트 실행

http://localhost:8080가 아닌 https://localhost:8080으로 접속해야 작동하는 것을 확인할 수 있다.


3. HTTP2란?

  • HTTP는 그림과 같이 기본적으로 1번의 연결로 1개의 리소스를 요청할 수 있다. 따라서 동시 요청이 어렵고 느리다.
  • 만약 총 4개의 데이터 a, b, c, d가 있다고 할 때 a가 만약 요청 시간이 가장 길다면 b, c, d는 순차적으로 요청시간이 느려지게 될 것이다. 이를 HOL Blocking 이라 한다
  • 무거운 Header구조를 가지고 있어 속도가 느리다
  • HTTP2는 HTTP/1.1의 무거운 헤더 정보를 압축하는 HPACK방식을 사용하여 데이터의 크기를 줄였다
  • 하나의 연결에 한 번의 정보가 아닌 여러 개의 메시지를 전달하여 순서에 상관없이 Stream으로 받을 수 있게 개선되었다
  • HTTP/1.1보다 약 15~50% 향상된다고 한다 (웹 기준)

 

4. SpringBoot에 HTTP2 적용하기

#1) 사전 준비

  • 스프링 부트 2.2.5 RELEASE, Dependency로 spring Web사용
  • Maven 사용 (Gradle사용 가능)
  • JAVA 9, 내장 톰캣 9 버전 사용 (이 버전을 이용하지 않을 시 과정이 복잡하여 버전을 올리는 것을 추천)

 

#2) 인텔리제이에서 JAVA 1.8로 사용하다가 9 버전으로 바꾸고 에러가 나는 경우

File > ProjectStructure > Project Settings > project에 Project SDK 버전을 JAVA 9 버전으로 변경

File > ProjectStructure > Project Settings > Modules > Dependencies에 ModuleSDK버전을 JAVA 9 버전으로 변경

 

#3) application.properties 추가

키가 만들어졌다면 다음과 같은 내용을 추가한다. HTTP2는 SSL이 반드시 적용되어야 사용할 수 있다. HTTPS 과정을 마치고 진행해야 한다.

server.ssl.key-store= keystore.p12
server.ssl.key-store-password= 본인이 입력한 패스워드
server.ssl.key-store-type= PKCS12
server.ssl.key-alias= spring
server.http2.enabled=true

#4) 프로젝트 실행

프로젝트 실행 후 다음과 같이 요청을 날려보면 HTTP/2로 통신하는 것을 확인할 수 있다.

curl -I -k --http2 https://localhost:8080

 

반응형
반응형

1. 프로젝트 생성

 

다음과 같이 Spring Boot의 Spring Starter Project를 선택한다.

 

이후 다음과 같은 화면에서 Name을 원하는 이름으로 설정한다. 이 프로젝트에서는 Maven을 사용했으나 Gradel을 사용해도 무방하다.

이후 웹 서버 프로젝트를 만들예정이므로 다음과같이 web에 spring web을 선택 후 프로젝트를 생성한다

 

2. 프로젝트 실행하기

다음과 같이 스프링 프로젝트를 실행한다. 이후 localhost:8080으로 접속하면 내장된 톰캣으로 서버가 동작하고있는것을 확인할 수 있다.

 

반응형

+ Recent posts