스프링 프레임워크

 

①  스프링 프레임워크(Spring Framework)

  • 여러 프레임워크들 중 자바(JAVA)를 기반으로 하는 프레임워크 이다.
  • 대한민국 공공기관의 웹 서비스 개발 시 사용을 권장하고 있는 전자정부 표준프레임워크 이다.
  • 스프링의 다른 프레임워크와 가장 큰 차이점은 다른 프레임워크들의 포용이다. 이는 다시말해 기본 뼈대를 흔들지 않고, 여러 종류의 프레임워크를 혼용해서 사용할 수 있다는 점.

 

② 스프링 프레임워크 특징

  •  POJO(Plan Old Java Object)기반의 구성
    - 코드를 개발할 때 개발자가 특정한 라이버리나 컨테이너의 기술에 종속적이지 않다는 것을 의미
    - 쉽게말해 Java코드를 이용해서 객체를 구성하는 방식을 그대로 스프링에서 사용할 수 있다는 의미

 

  • 의존성 주입
    -  의존성 주입은 하나의 객체가 다른객체의 의존성을 제공하는 테크닉
    - "어떤 객체가 필요한 객체를 외부에서 밀어 넣는다."는 의미
    - "의존성 주입"을 사용하여 갖는 장점은 '주입을 받는 입장에서는 어떤 객체인지 신경 쓸 필요가 없다.', '어떤 객체에 의존하든 자신의 역할은 변하지 않는다.'이다.
    - "ApplicationContext"라는 존재가 필요한 객체들을 생성하고, 필요한 객체들을 주입하는 역할을 해주는 구조
    - "ApplicationContext가 관리하는 객체들을 "빈(Bean)"이라고 한다.
    - 빈과 빈 사이의 의존 관계를 'xml 설정', '어노테이션 설정', 'Java 설정 방식'을 통해서 처리 할 수 있다.

 

  • 관점지향프로그래밍(AOP)의 지원
    - 대부분의 시스템에서 '보안'이나 '로그', '트랜잭션'과 같이 무엇을 실행을 하든 반드시 처리가 필요한 부분이 있다. 이를 '횡단 관심사(cross-concern)'라고 한다. 
    - AOP는 이러한 횡단 관심사를 모듈로 분리하는 프로그래밍 패러다임이다.
    - 이 패러다임을 통해서 반복적인 코드를 줄이고, 핵심 비즈니스 로직에만 집중을 할 수 있다.

 

  • 높은 확장성
    - 스프링 프레임워크에 통합하기 위해 간단하게 기존 라이브러리를 감싸는 정도로 스프링에서 사용이 가능하다.
    - 따라서 수많은 라이브러리가 이미 스프링에서 지원되고 있고 스프링에서 사용되는 라이브러리를 별도로 분리하기도용이하다.

 

③ 스프링 프레임워크 사용이유(장점)

  • 정형화 되어 있기 때문에 일정수준의 품질을 기대 할 수 있다.
  • 개발 후 유지보수 및 기능의 확장성에서도 품질을 보장한다.
  • '전자표준 프레임워크'기 때문에 해당 프레임워크의 수요가 크다.(한국 한정)

 

④ 스프링 프레임워크 단점

  • 내부에서 많은 기능을 가졌기 때문에 상당히 무겁다.
  • 분명 많은 기능을 제공해서 편리하지만, 이 기능들을 습득하기위해 상당한 노력과 시간이 필요하다.

 

 

참고자료 : 

https://kimvampa.tistory.com/35

 

생성자 자동완성 어노테이션

@AllArgsConstructor

모든 변수를 사용하는 생성자를 자동완성 시켜주는 어노테이션

@AllArgsConstructor
public class Order {
    private String food;
    private int price;
    private String makers;

    /*@AllArgsConstructor를 사용하면 아래와 같은 생성자를 자동 생성할 수 있다.
    public Order(String food, int price, String makers) {
        this.food = food;
        this.price = price;
        this.makers = makers;
    }
    */
    }

 

@NoArgsConstructor

어떠한 변수도 사용하지 않는 기본 생성자를 자동완성 어노테이션이다.

@NoArgsConstructor
public class Order {
    private String food;
    private int price;
    private String makers;

    /*@NoArgsConstructor 사용하면 아래와 같은 생성자를 자동 생성할 수 있다.
    public Order() {

    }
    */
}

 

@RequireArgsConstructor

특정 변수만을 활용하는 생성자를 자동완성 시켜주는 어노테이션이다. 생성자의 인자로 추가할 변수에 @NonNull 어노테이션을 붙여서 해당 변수를 생성자의 인자로 추가할 수 있다. 아니면 해당 변수를 final로 선언해도 의존성을 주입받을 수 있다.

@RequireArgsConstructor
public class Order {
    @NotNull
    private String food;
    private final int price;
    private String makers;

    /*@RequireArgsConstructor 사용하면 아래와 같은 생성자를 자동 생성할 수 있다.
    public Order(String food, int price) {
        this.food = food;
        this.price = price;
    }
    */
}

@Builder(번외)
Builder 패턴이란 점증적 생성자 패턴과 자바빈즈 패턴의 단점을 보완하기 위해 사용되는 디자인패턴이다. @Builder 어노테이션을 사용하면 클래스 객체 생성시 Builder 패턴을 적용시켜준다. 모든 변수들에 대해 build하기를 원한다면 클래스 위에 @Builder를 붙이면 되지만, 특정 변수만을 build하기 원한다면 생성자를 작성하고 그 위에 @Builder 어노테이션을 붙여주면 된다.

Builder 패턴을 적용시 장점

  • 불필요한 생성자의 제거
  • 데이터의 순서에 상관없이 객체생성 가능
  • 명시적 선언으로 이해하기가 쉬우며 각 인자가 어떤 의미인지 알기 쉽다.
  • setter메서드가 없으므로 변경 불가능한 객체를 만들수있다.
  • 정보들을 다 받은 후에 한번에 객체를 생성하므로 객체일관성이 깨지지 않는다.
  • build()함수가 null인지 체크해주므로 검증이 가능한다.

 

의존성 주입 방법

생성자 주입(Constructor Injection): 생성자를 통해 의존 관계를 주입하는 방법

@Service
public class UserService {

    private UserRepository userRepository;
    private PasswordEncoder passwordEncoder;

    @Autowired
    public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder) {
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }    
}

생성자가 의존성 주입되는 클래스 내에 1개만 존재할 경우 @Autowired 어노테이션을 생략할 수 있다.
생성자 주입을 이용하면 필드 객체에 final(더이상 수정 불가능) 키워드를 사용할 수 있으며, 컴파일 시점에 누락된 의존성을 확인할 수 있다.

@Service
@RequireArgsConstuctor
public class UserService {
    private final UserRepository userRepository;
    private final PasswordEncoder passwordEncoder;

}

주입 시킬 객체(UserRepository, PasswordEncoder)에 final 키워드를 붙임으로써 UserService가 스프링 컨테이너에 Bean으로 등록될 때 UserRespository와 PasswordEncoder를 주입시켜준다.

 

수정자 주입(Setter Injection): Setter를 통해 의존 관계를 주입하는 방법

@Service
public class UserService {

    private UserRepository userRepository;
    private PasswordEncoder passwordEncoder;

    @Autowired
    public setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }  

    @Autowired
    public serPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }   
}

주입받는 객체가 변경될 가능성이 있는 경우에 사용한다.

 

필드 주입(Field Injection): 필드에 바로 의존 관계를 주입하는 방법

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private PasswordEncoder passwordEncoder;
}

필드 주입은 외부에서 접근이 불가능하다는 단점이 존재한다. 또한, 필드 주입은 DI 프레임워크가 존재해야 하므로 프레임 워크와의 의존성이 강하게 결합된다. 따라서 애플리케이션의 구동에 무관한 테스트 코드를 작성하거나 불가피하게 설정해야할 경우를 제외하고 사용을 지양해야한다.

실제 개발 상황에서는 의존 관계의 변경이 필요한 경우는 드물다. 수정자 주입과 같이 수정의 가능성을 열어둔 상태로 개발을 진행하게 되면 유지 보수성이 떨어진다. 그러므로 의존 관계 주입시, 생성자 주입을 통해 변경의 여지를 두지 않고 불변성을 보장하는 것이 좋다.

 

생성자 주입을 사용할 경우의 장점

① 순환 참조 방지

-> 애플리케이션 구동시 객체의 생성 시점에서 에러(컴파일 에러)가 발생하므로 순환 참조 문제를 방지할 수 있다.

② 테스트 코드 작성 용이

-> 생성자 주입을 사용하면 컴파일 시점에 객체를 주입받아 테스트 코드를 작성할 수 있으며, 주입하는 객체가 누락된 경우 컴파일 시점에 오류를 발견할 수 있다

③ 객체의 불변성을 확보할 수 있으며, 객체의 변이를 방지한다.

-> 애플리케이션이 구동되어 @Component 어노테이션을 통해 Spring Bean으로 등록된 final 키워드를 가진 객체들은 객체 생성 이후 내부 상태가 변화하지 않는다.(read-only 메소드만 제공)

참고자료
참고자료2

 


참고자료: https://esoongan.tistory.com/82

 

[JAVA] 빌더패턴 (Builder Pattern) , @Builder

entity나 Dto객체에 값을 넣어줄때 롬복의 빌더 애노테이션(@Builder)을 종종 사용하곤 하는데 완벽히 이해를 하지 못한것같아 정리해보았다! 빌더패턴이란? 디자인패턴중 하나로, 생성과 표현의 분

esoongan.tistory.com

 

 

JWT 사용 흐름

1. Client 가 username, password 로 로그인 성공 시

  • "로그인 정보" → JWT 로 암호화 (Secret Key 사용)
  • JWT 를 Client 응답에 전달. (JWT 전달방법은 개발자가 정함 - 예) 응답 Header 에 아래 형태로 JWT 전달)
  • Client 에서 JWT 저장 (쿠키, Local storage 등)

2. Client 에서 JWT 통해 인증방법

  1. JWT 를 API 요청 시마다 Header 에 포함 - 예) HTTP Headers
  2. Server
    1. Client 가 전달한 JWT 위조 여부 검증 (Secret Key 사용)
    2. JWT 유효기간이 지나지 않았는지 검증
    3. 검증 성공시, JWT → 에서 사용자 정보를 가져와 확인  ex) GET /api/products : JWT 보낸 사용자의 관심상품 목록 조회

 

JWT 구조

  • JWT 는 누구나 평문으로 복호화 가능
  • 하지만 Secret Key 가 없으면 JWT 수정 불가능 → 결국 JWT 는 Read only 데이터

인증과 인가의 차이

  • 인증(Authentication) : 해당 유저가 실제 유저인지 인증하는 개념. 스마트폰에 지문인식, 이용하는 사이트에 로그인 등과 같이, 실제 그 유저가 맞는지를 확인하는 절차를 의미한다. 일반적으로 웹 어플리케이션은 아래 설명할 두가지 방법을 통해서 인증을 처리한다. 
  • 인가(Authorization) : 해당 유저가 특정 리소스에 접근이 가능한지 허가를 확인하는 개념. 예를들어 관리자 페이지-관리자 권한 같은 것들이 해당된다.

 

웹 어플리케이션 인증의 특수성

  1. 일반적으로 서버-클라이언트 구조로 되어있고, 실제로 이 두가지 요소는 아주 멀리 떨어져 있다.
  2. 그리고 Http 라는 프로토콜을 이용하여 통신하는데, 그 통신은 비연결성(Connectionless) 무상태(Stateless)로 이루어진다.
  3. 보통 모바일/웹 서비스의 인증은 HTTP 메세지의 헤더에 인증 수단을 넣어 요청을 보낸다.

비연결성(Connectionless) 무상태(Stateless) 의미 ↓

더보기

비연결성(Connectionless)서버와 클라이언트가 연결되어 있지 않다는 것. 채팅이나 게임 같은 것들을 하지 않는 이상 서버와 클라이언트는 실제로 연결되어 있지 않다. 그 이유는 리소스를 절약하기 위해서 인데, 만약 서버와 클라이언트가 실제로 계속 연결되어있다면 클라이언트는 그렇다고 쳐도, 서버의 비용이 기하급수적으로 늘어나기 때문. 그래서 서버는 실제로 하나의 요청에 하나의 응답을 내버리고 연결을 끊어버리고있다 라고 생각하면 된다.

 

무상태(Stateless)서버가 클라이언트의 상태를 저장하지 않는다는 것. 기존의 상태를 저장하는 것들도 마찬가지로 서버의 비용과 부담을 증가시키는 것 이기 때문에 기존의 상태가 없다고 가정하는 프로토콜을 이용해 구현되어 있다. 실제로 서버는 클라이언트가 직전에, 혹은 그 전에 어떠한 요청을 보냈는지 관심도 없고 전혀 알지 못한다.

 

인증방식 (1) 쿠키 - 세션 방식

 

https://tansfil.tistory.com/58

  • 쿠키-세션 방식은 서버가 특정 유저가 로그인 되었다는 상태를 저장하는 방식
  • 세션은 서버에서 가지고 있는 정보이며 쿠키는 사용자에게 발급된 세션을 열기 위한 열쇠(SESSION ID)를 의미
  • 인증과 관련된 아주 약간의 정보만 서버가 가지고 있게 되고 유저의 이전 상태의 전부는 아니더라도 인증과 관련된 최소한의 정보는 저장해서 로그인을 유지시킨다는 개념
  • 결과적으로 Session/Cookie 인증 방식을 사용하는 이유는 서버에 인증의 책임을 전가하는 것이다.
  • 더보기
    1. 사용자가 로그인 요청을 보냅니다.
    2. 서버는 DB의 유저 테이블을 뒤져서 아이디 비밀번호를 대조해봐야겠죠?
    3. 실제 유저테이블의 정보와 일치한다면 인증을 통과한 것으로 보고 “세션 저장소”에 해당 유저가 로그인 되었다는 정보를 넣습니다.
    4. 세션 저장소에서는 유저의 정보와는 관련 없는 난수인 session-id를 발급합니다.
    5. 서버는 로그인 요청의 응답으로 session-id를 내어줍니다.
    6. 클라이언트는 그 session-id를 쿠키라는 저장소에 보관하고 앞으로의 요청마다 세션아이디를 같이 보냅니다. (주로 HTTP header에 담아서 보냅니다!)
    7. 클라이언트의 요청에서 쿠키를 발견했다면 서버는 세션 저장소에서 쿠키를 검증합니다.
    8. 만약 유저정보를 받아왔다면 이 사용자는 로그인이 되어있는 사용자겠죠?
    9. 이후에는 로그인 된 유저에 따른 응답을 내어줍니다.아래는 그림의 각 번호에 따른 설명

 

 

 


① 장점

  1. 세션/쿠키 방식은 기본적으로 쿠키를 매개로 인증을 거치기 때문에 비교적 안전한 방식이다.
    • 여기서 쿠키는 세션 저장소에 담긴 유저 정보를 얻기 위한 열쇠를 의미한다.
    • 따라서 쿠키가 담긴 HTTP 요청이 도중에 노출되더라도 쿠키 자체(세션 ID)는 유의미한 값을 갖고있지 않다(중요 정보는 서버 세션)
    • 헤더에 직접적으로 계정정보를 담아 인증을 거치는 것 보단 안전하다.
  2. 사용자 A는 1번, 사용자 B는 2번 이런식으로 고유의 ID값을 발급받게 된다. 그렇게 되면 서버에서는 쿠키 값을 받았을 때 일일이 회원정보를 확인할 필요 없이 바로 어떤 회원인지를 확인할 수 있어 서버의 자원에 접근하기 용이하다.

② 단점

  1. 장점 1에서 쿠키를 탈취당하더라도 안전할 수 있다고 언급했지만 문제가 하나 있다. 만일 A 사용자의 HTTP 요청을 B 사용자(해커)가 가로챘다면 그 안에 들어있는 쿠키도 충분히 훔칠 수 있다. 그리고 B 사용자는 그 훔친 쿠키를 이용해 HTTP 요청을 보내면 서버의 세션저장소에서는 A 사용자로 오인해 정보를 잘못 뿌려주게 된다.(세션 하이재킹 공격이라고 한다) 
    • 해결책 ↓
    • 더보기
      1. HTTPS를 사용해 서버와 클라이언트 간의 주고받는 정보를 암호화하여 요청 자체를 탈취해도 안의 정보를 읽기 힘들게 한다. 2. 세션에 유효시간을 넣어준다. 
  2. 서버에서 세션 저장소를 사용한다. 따라서 서버에서 추가적인 저장공간을 필요로 하게되고 자연스럽게 부하도 높아질 것. 

 

인증 방식 (2) JWT 기반 인증

https://tansfil.tistory.com/58

 

  • JWT(JSON Web Token)란 인증에 필요한 정보들을 암호화시킨 토큰을 의미
  • JWT 기반 인증은 쿠키/세션 방식과 유사하게 JWT 토큰(Access Token)을 HTTP 헤더에 실어 서버가 클라이언트를 식별한다.
  • 아래는 그림의 각 번호에 따른 설명 
  • 더보기
    1. 사용자가 로그인 요청을 보냅니다.
    2. 서버는 DB의 유저 테이블을 뒤져서 아이디 비밀번호를 대조해봐야겠죠?
    3. 실제 유저테이블의 정보와 일치한다면 인증을 통과한 것으로 보고 유저의 정보를 JWT로 암호화 해서 내보냅니다
    4. 서버는 로그인 요청의 응답으로 jwt 토큰을 내어줍니다.
    5. 클라이언트는 그 토큰을 저장소에 보관하고 앞으로의 요청마다 토큰을 같이 보냅니다.
    6. 클라이언트의 요청에서 토큰을 발견했다면 서버는 토큰을 검증합니다.
    7. 이후에는 로그인 된 유저에 따른 응답을 내어줍니다.

① 장점
  1. 간편하다. 세션/쿠키는 별도의 저장소의 관리가 필요하다. 그러나 JWT는 발급한 후 검증만 하면 되기 때문에 추가 저장소가 필요 없다. 이는 Stateless 한 서버를 만드는 입장에서는 큰 강점이다. 여기서 Stateless는 어떠한 별도의 저장소도 사용하지 않는, 즉 상태를 저장하지 않는 것을 의미. 이는 서버를 확장하거나 유지,보수하는데 유리하다.
  2. 확장성이 뛰어나다. 토큰 기반으로 하는 다른 인증 시스템에 접근이 가능하다. 예를 들어 Facebook 로그인, Google 로그인, 카카오 OAuth2 로그인 등은 모두 토큰을 기반으로 인증을 한다. 이에 선택적으로 이름이나 이메일 등을 받을 수 있는 권한도 받을 수 있다.
  3. 동시 접속자가 많을 때 서버 측 부하를 낮춰줄 수 있다.

② 단점

  1. 이미 발급된 JWT에 대해서는 돌이킬 수 없다. 세션/쿠키의 경우 만일 쿠키가 악의적으로 이용된다면, 해당하는 세션을 지워버리면 된다. 하지만 JWT는 한 번 발급되면 유효기간이 완료될 때 까지는 계속 사용이 가능하다. 따라서 악의적인 사용자는 유효기간이 지나기 전까지 신나게 정보들을 털어갈 수 있다. 
    • 해결책 ↓
    • 더보기
      기존의 Access Token의 유효기간을 짧게 하고 Refresh Token이라는 새로운 토큰을 발급한다. 그렇게 되면 Access Token을 탈취당해도 상대적으로 피해를 줄일 수 있다.
  2. Payload 정보가 제한적이다. 위에서 언급했다시피 Payload는 따로 암호화되지 않기 때문에 디코딩하면 누구나 정보를 확인할 수 있다. (세션/쿠키 방식에서는 유저의 정보가 전부 서버의 저장소에 안전하게 보관된다) 따라서 유저의 중요한 정보들은 Payload에 넣을 수 없다.
  3. JWT의 길이. 세션/쿠키 방식에 비해 JWT의 길이는 길다. 따라서 인증이 필요한 요청이 많아질 수록 서버의 자원낭비가 발생하게 된다. = 비용 증가
  4. 구현의 복잡도가 증가한다.
  5. Secret key 유츌 시 JWT 조작 가능하다.

 

 

쿠키세션과 JWT의 차이

  • 가장 큰 차이점은 세션/쿠키는 세션 저장소에 유저의 정보를 넣는 반면, JWT는 토큰 안에 유저의 정보들이 넣는다는 점
  • 물론 클라이언트 입장에서는 HTTP 헤더에 세션ID나 토큰을 실어서 보내준다는 점에서는 동일하나, 서버 측에서는 인증을 위해 암호화를 하냐, 별도의 저장소를 이용하냐는 차이가 발생한다.

 


자료 출처 :

개인 과제 질문

 

1. 처음 설계한 API와 ERD에 변경사항이 있었나요? 변경되었다면 어떤 점 때문일까요? 첫 설계의 중요성에 대해 생각해보세요.

과제 레벨 1 까지만 구현했기 때문에 처음 설계한 API와 ERD에 큰 변경사항은 없었지만, 만약 레벨2로 넘어가야 했다면, 게시문의 댓글을 담당하는 Comment Entity를 하나 더 생성하고 FK를 이용해 게시글과 맵핑해주는 작업을 추가하는 수정이 필요했을 것 같다.


2. ERD를 먼저 설계한 후 Entity를 개발했을 때 어떤 점이 도움이 되셨나요?
 

ERD(Entity Relationship Diagram)

  • 엔티티와 이들 간의 관계를 알기 쉽게 약속된 도형을 이용하여 일목요연하게 그림으로 표현한 것이다.
  • ER모델의 구성요소는 엔티티(Entity), 관계(Relationship), 속성(Attribute) 을 기본으로 하여 관계 수, 식별자, 서브타입 등으로 세분화 할 수 있다.
  • 문장 형식의 업무 처리 규정을 약속된 도형 형태로 나타내어 전체 업무 및 데이터의 구조를 쉽게 파악할 수 있다.
  • 문장으로 기술하지 않고 공통적인 약속을 통해 표현함으로써 업무의 파악과 이해가 용이하다.
  • 데이터베이스를 구현할 때 정규화(Normalization)된 테이블을 만들기 위한 근거 자료로 활용한다.

3. JWT를 사용하여 인증/인가를 구현 했을 때의 장점은 무엇일까요?

  1. 간편하다. 세션/쿠키는 별도의 저장소의 관리가 필요하다. 그러나 JWT는 발급한 후 검증만 하면 되기 때문에 추가 저장소가 필요 없다. 이는 Stateless 한 서버를 만드는 입장에서는 큰 강점이다. 여기서 Stateless는 어떠한 별도의 저장소도 사용하지 않는, 즉 상태를 저장하지 않는 것을 의미. 이는 서버를 확장하거나 유지,보수하는데 유리하다.
  2. 확장성이 뛰어나다. 토큰 기반으로 하는 다른 인증 시스템에 접근이 가능하다. 예를 들어 Facebook 로그인, Google 로그인, 카카오 OAuth2 로그인 등은 모두 토큰을 기반으로 인증을 한다. 이에 선택적으로 이름이나 이메일 등을 받을 수 있는 권한도 받을 수 있다.
  3. 동시 접속자가 많을 때 서버 측 부하를 낮춰줄 수 있다.

4. 반대로 JWT를 사용한 인증/인가의 한계점은 무엇일까요?

  1. 이미 발급된 JWT에 대해서는 돌이킬 수 없다. 세션/쿠키의 경우 만일 쿠키가 악의적으로 이용된다면, 해당하는 세션을 지워버리면 된다. 하지만 JWT는 한 번 발급되면 유효기간이 완료될 때 까지는 계속 사용이 가능하다. 따라서 악의적인 사용자는 유효기간이 지나기 전까지 신나게 정보들을 털어갈 수 있다. 
  2. Payload 정보가 제한적이다. 위에서 언급했다시피 Payload는 따로 암호화되지 않기 때문에 디코딩하면 누구나 정보를 확인할 수 있다. (세션/쿠키 방식에서는 유저의 정보가 전부 서버의 저장소에 안전하게 보관된다) 따라서 유저의 중요한 정보들은 Payload에 넣을 수 없다.
  3. JWT의 길이. 세션/쿠키 방식에 비해 JWT의 길이는 길다. 따라서 인증이 필요한 요청이 많아질 수록 서버의 자원낭비가 발생하게 된다. = 비용 증가
  4. 구현의 복잡도가 증가한다.
  5. Secret key 유츌 시 JWT 조작 가능하다.

5. 만약 댓글 기능이 있는 블로그에서 댓글이 달려있는 게시글을 삭제하려고 한다면 무슨 문제가 발생할까요? Database 테이블 관점에서 해결방법이 무엇일까요?
 

게시글에 달려있는 댓글 또한 동시에 삭제해야 한다. @OneToMany(cascade= CASCADE.REMOVE)를 사용하여 게시글이 삭제 될 때 그와 연관된 여러개의 댓글도 동시에 삭제되도록 해결할 수 있을 것 같다.


6. IoC / DI 에 대해 간략하게 설명해 주세요!
 

DI(Dependency Injection)

  • DI(Dependency Injection)란 스프링이 다른 프레임워크와 차별화되어 제공하는 의존 관계 주입 기능이다.
  • 객체를 직접 생성하는 게 아니라 외부에서 생성한 후 주입 시켜주는 방식이다.
  • DI(의존성 주입)를 통해서 모듈 간의 결합도가 낮아지고 유연성이 높아진다.

Ioc(Inversion of Control)

  • IoC(Inversion of Control)란 "제어의 역전" 이라는 의미로, 말 그대로 메소드나 객체의 호출작업을 개발자가 결정하는 것이 아니라, 외부에서 결정되는 것을 의미한다.
  • IoC는 제어의 역전이라고 말하며, 간단히 말해 "제어의 흐름을 바꾼다"라고 한다.
  • 객체의 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하여 가독성 및 코드 중복, 유지 보수를 편하게 할 수 있게 한다.

Spring 공통 질문

1. 스프링 프레임워크

[19] 스프링 프레임워크

 

[19] 스프링 프레임워크

스프링 프레임워크 ① 스프링 프레임워크(Spring Framework) 여러 프레임워크들 중 자바(JAVA)를 기반으로 하는 프레임워크 이다. 대한민국 공공기관의 웹 서비스 개발 시 사용을 권장하고 있는 전자

leejincha.tistory.com

 

2. 스프링에서 DI (의존성 주입) 를 사용하는 이유

[20] 의존성 주입 DI(Dependency Injection)

 

[20] 의존성 주입 DI(Dependency Injection)

스프링에서 DI (의존성 주입) 를 사용하는 이유 ① DI(의존성 주입)이란? DI란 외부에서 두 객체 간의 관계를 결정해주는 디자인 패턴으로, 인터페이스를 사이에 둬서 클래스 레벨에서는 의존관계

leejincha.tistory.com


3. ORM, JPA, Spring Data JPA 

[21] ORM, JPA, Spring Data JPA

 

[21] ORM, JPA, Spring Data JPA

ORM, JPA, Spring Data JPA ORM : 객체(Object)와 관계형 데이터(Relational data) 를 매핑하기 위한 기술이다. 객체와 테이블 관계를 바탕으로 SQL문장을 자동으로 생성하여 객체로 DB를 조작하게 하는 기술. JPA :

leejincha.tistory.com


인증, 인가의 차이

[18] 인증과 인가 (1) 세션/쿠키, JWT

 

[18] 인증과 인가 (1) 세션/쿠키, JWT

인증과 인가의 차이 인증(Authentication) : 해당 유저가 실제 유저인지 인증하는 개념. 스마트폰에 지문인식, 이용하는 사이트에 로그인 등과 같이, 실제 그 유저가 맞는지를 확인하는 절차를 의미

leejincha.tistory.com

참고자료 : https://jake-seo-dev.tistory.com/76


절차지향 프로그래밍, 객체지향 프로그래밍, 관점지향 프로그래밍 

 

① 절차지향 프로그래밍 (Procedural Programming)

  1. 컴퓨터가 해야 할 일을 시간의 흐름에 따라 순차적으로 프로그래밍하는 방식
  2. 장점
    1. 객체나 클래스를 만들 필요 없이 바로 프로그램을 코딩할 수 있어서 시간적으로 유리하다.
    2. 필요한 기능을 함수로 만들어 두기 때문에 같은 코드를 복사하지 않고 호출하여 사용할 수 있다.
    3. 프로그램의 흐름을 쉽게 추적할 수 있다.
  3. 단점
    1. 각 코드가 매우 유기성이 높기 때문에 수정하기가 힘들다. (새로운 데이터나 기능을 추가하기가 어려움)
    2. 프로그램 전체에서 코드를 재사용 할 수가 없어 프로젝트 개발 비용과 시간이 늘어날 수 있다.
    3. 유지보수 및 디버깅이 어렵다.

 

② 객체지향 프로그래밍 (Object-Oriented Programming)

  • 데이터와 기능(함수)들을 묶어 하나의 객체로 만들어 진행하는 방식 / 하나의 사물 (객체) 에 하나의 의미를 부여하는 것처럼 프로그래밍
  • 장점
    1. 모듈화, 캡슐화로 하드웨어가 같은 기능을 중복으로 연산하지 않도록해 유지보수에 용이하다.
    2. 모듈을 재활용 하기 때 문에 하드웨어의 처리양을 획기적으로 줄여줌.
    3. 객체지향적이기 때문에 현실 세계와 유사성에 의해 코드를 이해하기 쉽게 만든다.
    4. 객체는 그 자체가 하나의 프로그램이기 때문에 다른 프로그램에서 재사용이 가능하다.
  • 단점
    1. 대부분의 객체 지향 프로그램은 속도가 상대적으로 절차지향보다 느려지고 많은 양의 메모리를 사용하는 경향이 있다.
    2. 설계 과정에 시간이 많이 투자된다.

 

③ 관점지향 프로그래밍 (Aspect-Oriented Programming)

  1. 객체지향을 더욱 발전 시키기 위한 개념의 하나. 하나의 소프트웨어가 하나의 거대한 OOP로써 설계, 프로 그래밍 되었다면 이것을 각 기능별로 모듈화 해서 분리 시키는 개념.
  2. 관점지향의 핵심은 공통 모듈을 분리시켜 해당 소스 코드가 외부의 다른 클래스에서 존재하는 것.
  3. 장점
    1. 각 비즈니스 로직마다 복붙을 통해 생겨난 중복 코드가 사라진다.
    2. 각 비즈니스 로직을 구현하는 개발자는 자기 자신의 비즈니스 코드에만 집중할 수 있어 코드가 간결해지고, 유지보수가 쉬워진다.
    3. 재활용성이 더욱 높아진다.
  • CORE CONCERN(핵심관심): 각 서비스의 핵심 비즈니스 로직예: 계좌이체, 입출금, 이자계산
  • Crosscut Concern(횡단관심): 공통 모듈예: 보안, 예외처리, 로깅 등
  •  

팀 질문 ( 키워드 5개)

생성자 자동완성 어노테이션

@NoArgsConstructor

기본 생성자를 생성해준다.

이 경우 초기값 세팅이 필요한 final 변수가 있을 경우 컴파일 에러가 발생함으로 주의한다.

@NoArgsConstructor(force=true) 를 사용하면 null, 0 등 기본 값으로 초기화 된다.

 

@RequiredArgsConstructor

final 변수, Notnull 표시가 된 변수처럼 필수적인 정보를 세팅하는 생성자를 만들어준다.

 

@AllArgsConstructor

전체 변수를 생성하는 생성자를 만들어준다.

 

참고 자료 : https://minji6119.tistory.com/44


영속성 컨텍스트란?

  • 영속성 컨텍스트란 엔티티를 영구 저장 하는 환경 이라는 뜻
  • 어플리케이션(자바 코드 그 자체)이 데이터베이스에서 꺼내온 데이터 객체를 보관하는 역할을 한다.
  • 영속성 컨텍스트는 엔티티 매니저를 통해 엔티티를 조회하거나 저장할때 엔티티를 보관하고 관리한다.
  • 엔티티 매니저마다 개별적으로 부여되는, 어떠한 논리적 공간같은 개념으로 비유적으로 이해할 수 있다.
  • 자바의 엔티티 객체를 엔티티 매니저마다 가지고 있는 영속성 컨텍스트라는 공간에다 넣고 빼고 하면서 사용하는 것
  • “영속화 한다” 라는 말을 “엔티티 매니저가 자기의 영속성 컨텍스트에 넣어준다”로 이해할 수 있다.

Refresh token과 Access token

 

Access Token(JWT)를 통한 인증 방식의 문제는 만일 제 3자에게 탈취당할 경우 보안에 취약하다는 점입니다.

더보기

유효기간이 짧은 Token의 경우 그만큼 사용자는 로그인을 자주 해서 새롭게 Token을 발급받아야 하므로 불편합니다.

그러나 유효기간을 늘리자면, 토큰을 탈취당했을 때 보안에 더 취약해지게 됩니다. 

이때 “그러면 유효기간을 짧게 하면서  좋은 방법이 있지는 않을까?”라는 질문의 답이 바로 "Refresh Token"입니다. 

해결법 

Refresh Token은 Access Token과 똑같은 형태의 JWT입니다. 처음에 로그인을 완료했을 때 Access Token과 동시에 발급되는 Refresh Token은 긴 유효기간을 가지면서, Access Token이 만료됐을 때 새로 발급해주는 열쇠가 됩니다(여기서 만료라는 개념은 그냥 유효기간을 지났다는 의미입니다.) 

 

사용 예

더보기

Refresh Token의 유효기간은 2주, Access Token의 유효기간은 1시간이라 하겠습니다. 사용자는 API 요청을 신나게 하다가 1시간이 지나게 되면, 가지고 있는 Access Token은 만료됩니다. 그러면 Refresh Token의 유효기간 전까지는 Access Token을 새롭게 발급받을 수 있습니다. 

 

* Access Token은 탈취당하면 정보가 유출되는건 동일합니다. 다만 짧은 유효기간 안에만 사용이 가능하기에 더 안전하다는 의미입니다. 

 * Refresh Token의 유효기간이 만료됐다면, 사용자는 새로 로그인해야 합니다. Refresh Token도 탈취될 가능성이 있기 때문에 적절한 유효기간 설정이 필요해보입니다(보통 2주로 많이 잡더군요)

 

 

참고 자료 : https://tansfil.tistory.com/59?category=475681


JWT 장단점

장점

  • 동시 접속자가 많을 때 서버 측 부하 낮춤
  • Client, Sever 가 다른 도메인을 사용할 때 - 예) 카카오 OAuth2 로그인 시 JWT Token 사용

단점

  • 구현의 복잡도 증가
  • JWT 에 담는 내용이 커질 수록 네트워크 비용 증가 (클라이언트 → 서버)
  • 기 생성된 JWT 를 일부만 만료시킬 방법이 없음
  • Secret key 유출 시 JWT 조작 가능

느슨한 결합 / 강한 결합 

강한 결합

객체 내부에서 다른 객체를 생성하는 것은 강한 결합도를 가지는 구조이다. A 클래스 내부에서 B 라는 객체를 직접 생성하고 있다면, B 객체를 C 객체로 바꾸고 싶은 경우에 A 클래스도 수정해야 하는 방식이기 때문에 강한 결합이다.

 

느슨한 결합

객체를 주입 받는다는 것은 외부에서 생성된 객체를 인터페이스를 통해서 넘겨받는 것이다. 이렇게 하면 결합도를 낮출 수 있고, 런타임시에 의존관계가 결정되기 때문에 유연한 구조를 가진다.

강한 결합에서 느슨한 결합으로 바뀌는 것을 IoC(제어 반전)이라고 하고, SOLID 원칙에서 O 에 해당하는 Open Closed Principle 을 지키기 위해서 IoC를 한다고 생각할 수 있다.

*Open Closed Principle란 객체 지향의 5대 원칙 중 하나로, 확장에는 열려(Open) 있으나, 변경에는 닫혀(Closed)있어야 한다는 것을 의미한다. (유지 보수를 위해 처음부터 설계를 잘해야 한다는 의미인듯)

'Coding > Spring' 카테고리의 다른 글

+ (추가) JWT 사용 흐름 재정리  (0) 2022.12.07
[18] 인증과 인가 (1) 세션/쿠키, JWT  (1) 2022.12.07
[16] IntelliJ 단축키 모음  (0) 2022.12.07
[15] JPA (2) 심화  (0) 2022.12.07
[14] JPA (1)  (0) 2022.12.06

+ Recent posts