[백엔드 기초] 백엔드 기초 개념정리

2025. 10. 22. 21:04·Spring/백엔드 기초

👍 무엇을 새롭게 알았는지

Spring에서 Bean의 개념에 대한 학습을 진행

- 같은 타입의 Bean이 두개일 때 발생하는 현상을 확인하기

  • food라는 패키지 내에 Food(interface), Chicken(class), Pizza(class)를 생성하여 연결하였음 
    • 연결되는 부분은 같은 Food 타입으로 연결되는 상황
// Food.java (interface)

package com.sparta.springauth.food;

public interface Food {
    void eat();
}

 

// Chicken.java (class)

package com.sparta.springauth.food;

import org.springframework.stereotype.Component;

@Component
public class Chicken implements Food {
    @Override
    public void eat() {
        System.out.println("치킨을 먹습니다.");
    }
}

 

package com.sparta.springauth.food;

import org.springframework.stereotype.Component;

@Component
public class Pizza implements Food {
    @Override
    public void eat() {
        System.out.println("피자를 먹습니다.");
    }
}

 

  • 두 클래스 모두 @Component 를 통해 Bean으로 등록되어 있으며 같은 타입으로 연결되어 있어도 오류는 발생하지 않음
    • 해당 부분을 테스트하기 위해 BeenTest.java 파일을 생성
// BeanTest.java

package com.sparta.springauth;

import com.sparta.springauth.food.Food;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class BeenTest {

    @Autowired
    Food food;

    @Test
    @DisplayName("테스트")
    void test1() {
        food.eat();
    }
}
  • 이렇게 연결된 상황에서는 @Autowired로 Food 타입을 주입받으려 할 때 오류가 발생
    • 어떤 Bean을 받아야 할 지 이해하지 못해 명시가 필요함
    • 이를 해결하기 위해서는 3가지의 해결방법이 있음

1. Bean 이름 명시하기 

package com.sparta.springauth;

import com.sparta.springauth.food.Food;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class BeenTest {

    @Autowired
    Food chicken;

    @Autowired
    Food pizza;

    @Test
    @DisplayName("테스트")
    void test1() {
        chicken.eat();
        pizza.eat();
    }
}
  • 이렇게 각 Bean의 이름을 명시하여 활용하면 정상적으로 구현체가 연결되었기 때문에 정상적으로 코드 구성이 완료됨

 

2. @Primary 사용하기

package com.sparta.springauth.food;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

@Component
@Primary
public class Chicken implements Food {
    @Override
    public void eat() {
        System.out.println("치킨을 먹습니다.");
    }
}
package com.sparta.springauth;

import com.sparta.springauth.food.Food;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class BeenTest {

    @Autowired
    Food food;

    @Test
    @DisplayName("Primary 와 Qualifier 우선순위 확인")
    void test1() {
        food.eat();
    }
}
  • @Primary 로 어노테이션을 받은 Chicken 클래스가 우선적으로 주입되어 출력되는 것을 확인할 수 있음

 

3. @Qualifier 사용하기

package com.sparta.springauth.food;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
@Qualifier("pizza")
public class Pizza implements Food {
    @Override
    public void eat() {
        System.out.println("피자를 먹습니다.");
    }
}
package com.sparta.springauth;

import com.sparta.springauth.food.Food;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class BeenTest {

    @Autowired
    @Qualifier("pizza")
    Food food;

    @Test
    @DisplayName("Primary 와 Qualifier 우선순위 확인")
    void test1() {
        food.eat();
    }
}
  • @Qualifier를 통해 Food 타입 주입 시 피자가 주입됨
    • 단 지정한 이름이 정확하게 일치하여야 오류발생하지 않음

 

→ 이를 통해 @Qualifier가 @Primary 보다 우선순위를 가지게 되고, 범용적으로 사용되는 Bean의 경우 @Primary를, 특정 상황에서 사용되는 Bean의 경우 @Qualifier를 사용하는 것을 권장함

 

→ 중복 설정 시 좁은 범위(@Qualifier)가 큰 범위(@Primary)보다 먼저 사용됨을 잊지 말 것

 

인증(Authentication) 과 인가(Authorization)

  • 인증
    • 인증은 해당 유저가 실제 유저인지 인증하는 개념
  • 인가
    • 해당 유저가 특정 리소스에 접근이 가능한지 허가를 확인하는 개념 (Ex. 관리자 권한)

쿠키와 세션

  • 쿠키
    • 클라이언트에 저장될 목적으로 생성한 작은 정보를 담은 파일
    • 구성 요소
      • Name (이름) : 쿠키를 구별하는데 사용되는 키 (중복될 수 없음)
      • Value (값) : 쿠키의 값
      • Domain (도메인) : 쿠키가 저장된 도메인
      • Path (경로) : 쿠키가 사용되는 경로
      • Expires (만료기한) : 쿠키의 만료기한 (만료기한이 지나면 삭제됨)
  • 세션
    • 서버에서 일정시간 동안 클라이언트 상태를 유지하기 위해 사용됨
    • 서버에서 클라이언트 별로 유일무이한 '세션 ID'를 부여한 후 클라이언트 별 필요한 정보를 서버에 저장 
    • 서버에서 생성한 '세션 ID'는 클라이언트의 쿠키값('세션 쿠키' 라고 부름)으로 저장되어 클라이언트 식별에 사용됨
항목 쿠키 (Cookie) 세션 (Session)
설명 클라이언트에 저장될 목적으로 생성한 작은 정보를 담은 파일 서버에서 일정시간 동안 클라이언트 상태를 유지하기 위해 사용
저장 위치 클라이언트 (웹 브라우저) 웹 서버
사용 예 사이트 팝업의 "오늘 다시보지 않기" 정보 저장 로그인 정보 저장
만료 시점 쿠키 저장 시 만료일시 설정 가능
(브라우저 종료시도 유지 가능)
다음 조건 중 하나가 만족될 경우 만료됨
1. 브라우저 종료 시까지
2. 클라이언트 로그아웃 시까지
3. 서버에 설정한 유지기간까지 해당 클라이언트의 재요청이 없는 경우
용량 제한 브라우저 별로 다름 (크롬 기준)
- 하나의 도메인 당 180개
- 하나의 쿠키 당 4KB(=4096byte)
개수 제한 없음
(단, 세션 저장소 크기 이상 저장 불가능)
보안 취약
(클라이언트에서 쿠키 정보를 쉽게 변경, 삭제 및 가로채기 당할 수 있음)
비교적 안전
(서버에 저장되기 때문에 상대적으로 안전)

 

JWT란?

: JWT(Json Web Token)란 JSON 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web Token. 즉 토큰의 한 종류

 

JWT 사용 이유

- 서버가 1대인 경우 

  • Session1이 모든 Client의 로그인 정보를 소유하고 있음

 

- 서버가 2대 이상인 경우

  • 서버의 대용량 트래픽 처리를 위해 서버 2대 이상 운영이 필요할 수 있음

  • Session 마다 다른 Client 로그인 정보를 가지고 있을 수 있음
    • Session1 : Client1, Client2, Client3
    • Session2 : Client4
    • Session3 : Client5, Client6
  • 만약 Client1 의 로그인 정보를 가지고 있지 않은 Server2나 Server3 에 API 요청을 하게 되면 문제가 발생하지 않을까?
    • 해결 방법
      1) Sticky Session : Client 마다 요청 Server를 고정
      2) 세션 저장소 생성하여 모든 세션을 저장

- 세션 저장소 생성 

  • Session storage가 모든 Client의 로그인 정보를 소유하고 있기 때문에 모든 서버에서 모든 Client의 API 요청을 처리할 수 있음

 

- JWT  사용

  • 로그인 정보를 Server에 저장하지 않고, Client 에 로그인 정보를 JWT로 암호화하여 저장 → JWT 통해 인증/인가

  • 모든 서버에서 동일한 Secret Key 소유
  • Secret Key 통한 암호화 / 위조 검증 (복호화 시)

 

  • JWT 장/단점
    1. 장점
      • 동시 접속자가 많을 때 서버 측 부하 낮춤
      • Client, Server 가 다른 도메인을 사용할 때
        • 예) 카카오 OAuth2 로그인 시 JWT Token 사용
    2. 단점
      • 구현의 복잡도 증가
      • JWT에 담는 내용이 커질 수록 네트워크 비용 증가 (클라이언트 → 서버)
      • 기 생성된 JWT 를 일부만 만료시킬 방법이 없음
      • Secret key 유출 시 JWT 조작 가능

'Spring > 백엔드 기초' 카테고리의 다른 글

[백엔드 기초] Filter, Spring Security  (0) 2025.10.24
[백엔드 기초] 쿠키를 활용한 인증 인가 개념 실습  (0) 2025.10.23
[백엔드 기초] 기초 개념 정리하기  (0) 2025.10.21
[Spring] 스프링을 위한 기본 개념 복습 및 학습 -2  (0) 2025.10.15
[Spring] 스프링을 위한 기본 개념 복습 및 학습  (0) 2025.10.14
'Spring/백엔드 기초' 카테고리의 다른 글
  • [백엔드 기초] Filter, Spring Security
  • [백엔드 기초] 쿠키를 활용한 인증 인가 개념 실습
  • [백엔드 기초] 기초 개념 정리하기
  • [Spring] 스프링을 위한 기본 개념 복습 및 학습 -2
stark77
stark77
하마의 IT 자기개발 이모저모, 백엔드 개발자로 거듭나기
  • stark77
    하마의 개발자 성장일기
    stark77
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 컴퓨터구조와 운영체제
        • 컴퓨터구조
        • 운영체제
      • SQL 기초
      • Spring
        • 백엔드 기초
        • Spring 실습
      • JAVA
        • Java 실습
      • HTML&CSS
        • HTML&CSS 실습
      • Git&GitHub
        • Git&GitHub 실습
      • 내배캠 끄적끄적
        • Today I Learned
      • 유용한 툴 및 사이트 정리
      • 취미
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    MVC
    SpringSecurity
    네트워크 기초
    웹소켓
    Til
    Java 문법기초
    HTML&CSS
    thymleaf
    RestTemplate
    git
    경합조건과 교착상태
    java
    백엔드 기초
    algorithm
    String.format
    Stomp
    Spriingboot
    백엔드 기초다지기
    WebSocket
    for문
    프로세스와 쓰레드
    BEAN
    jsp
    JPA
    객체지향프로그래밍
    객체지향
    Github
    다형성
    Spring
    실시간 데이터 처리
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
stark77
[백엔드 기초] 백엔드 기초 개념정리
상단으로

티스토리툴바