8/2 진행사항
✅ 알고리즘 3문제
✅ MSA강의 1-8 ~ 1-11
MSA 강의에서 JWT인증 실습이 진행되었는데 내용이 좀 부족한 거 같아
스프링 강의의 인증과 인가 내용을 정리해보려 한다.
인증과 인가
인증(Authentication)
-해당 유저가 실제 유저인지 확인 및 인증하는 행위
ex) 로그인
인가(Authorization)
-해당 유저가 특정 리소스에 접근이 가능한지 허가를 확인하는 개념
ex) 회원/비회원 여부에 따른 권한, 관리자페이지-관리자 권한
웹 애플리케이션 인증의 특수성
1. 서버-클라이언트 구조, 실제로 두 요소가 아주 멀리 떨어져 있다.
2. HTTP 프로토콜을 이용하여 통신한다.
HTTP는 비연결성 무상태로 이루어진다.
비연결성(Connectionless)란? 서버와 클라이언트가 연결되어 있지 않다는 것
무상태(Stateless)란? 서버가 클라이언트의 상태를 저장하지 않는다는 것
그렇다면 비연결성, 무상태 프로토콜에서 어떻게 유저의 인증을 유지시킬 수 있는 것일까?
첫 번째, 쿠키-세션방식의 인증을 알아보자
1. 사용자가 로그인 요청을 한다.
2. 회원 db에서 id와 pw을 확인한다.
3. 회원 db에서의 정보와 일치한다면 인증을 통과한 것으로 보고 세션 저장소에 유저가 로그인되었다는 정보를 넣는다.
4. 세션 저장소에서 난수인 session-id를 발급한다.
5. 로그인 요청의 session-id값을 응답으로 준다.
6. 클라이언트 쪽에서 session-id를 쿠키에 담아서 서버로 보낸다.
7. 쿠키를 검증한다.
8. 세션 저장소에서 유저정보를 받아온다.
9. 로그인된 유저의 응답을 준다.
두 번째, JWT 기반 인증을 알아보자
1. 사용자가 로그인 요청을 한다.
2. 회원 db에서 id와 pw을 확인한다.
3. 회원 db에서의 정보와 일치한다면 인증을 통과한 것으로 보고 유저의 정보를 jwt로 암호화해서 보낸다.
4. 서버는 로그인에 대한 응답으로 jwt 토큰을 준다.
5. 데이터 요청마다 HTTP 헤더에 토큰을 실어 보낸다.
6. 토큰 검증을 한다.
7. 로그인된 유저의 응답을 준다.
그렇다면 왜 JWT를 사용하는 걸까?
서버의 대용량 트래픽 처리를 위해 서버가 2대 이상 필요하다고 가정하자.
이때 Session마다 다른 클라이언트 정보를 가지고 있을 수 있다.
client1의 정보를 가지고 있지 않은 sever2에 요청하게 된다면 문제가 발생한다.
이를 해결하는 방법에는 세션 저장소 생성과 JWT 사용이 있다.
세션저장소를 사용하면 Session storage가 모든 클라이언트의 로그인 정보를 소유하고 있어서
모든 서버에서 모든 클라이언트의 API 요청 처리가 가능하다.
JWT를 사용하면 로그인 정보를 Server에 저장하지 않고, Client에 로그인 정보를 JWT로 암호화하여 저장한다.
JWT를 사용하면 동시 접촉자가 많을 때 서버 측 부하를 낮출 수 있다는 장점이 있다.
세션보다 가볍고 확장성이 좋으면서 관리가 용이하고 트래픽에 대한 부담이 낮은 특징으로
JWT를 사용하는 게 아닐까 생각이 든다.🤔
컨피그 서버 (Spring Cloud Config)
Spring Cloud Config는 분산 시스템 환경에서 중앙 집중식 구성 관리를 제공하는 프레임워크이다.
주요 기능은 다음과 같다.
1. 모든 마이크로 서비스의 설정은 중앙에서 관리한다.
2. 개발, 테스트, 운영 등 환경별로 구성을 분리하여 관리한다.
3. 설정 변경 시 애플리케이션을 재시작하지 않고 실시간 반영이 가능하다.
실시간 구성 변경 반영 방법
1. Spring Cloud Bus
2. /actuator/refresh/ 수동 호출 방법 (POST 요청)
3. Spring Boot DevTools
4. Git 저장소 사용
실습
product 애플리케이션이 local에서 동작할 때 포트 정보 및 메시지를 컨피그 서버에서 가져온다.
Config-service
ConfigApplication.java
@EnableConfigServer추가
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@SpringBootApplication
@EnableConfigServer
public class ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigApplication.class, args);
}
}
application.yml
server:
port: 18080
spring:
profiles:
active: native
application:
name: config-server
cloud:
config:
server:
native:
search-locations: classpath:/config-repo # 리소스 폴더의 디렉토리 경로
eureka:
client:
service-url:
defaultZone: http://localhost:19090/eureka/
resources 아래 config-repo 폴더 생성
product-service.yml과 product-service-local.yml을 생성한다.
(application.name과 일치해야 한다!!)
product-service.yml
server:
port: 19093
message: "product-service message"
product-service-local.yml
server:
port: 19083
message: "product-service-local message"
product-service
application.yml
포트를 0으로 임시 포트 설정, Config 서버 설정으로 덮어씌운다.
server:
port: 0 # 임시 포트, 이후 Config 서버 설정으로 덮어씌움
spring:
profiles:
active: local
application:
name: product-service
config:
import: "configserver:"
cloud:
config:
discovery:
enabled: true
service-id: config-server
management:
endpoints:
web:
exposure:
include: refresh
eureka:
client:
service-url:
defaultZone: http://localhost:19090/eureka/
message: "default message"
유레카서버 -> 컨피그 서버 -> 프로덕트 서버 순으로 run을 하면
product-service-local.yml 에서 설정한 포트 19083으로 설정된 것을 확인한다.
메시지 확인
메시지를 변경함 > 컨피그 서버 재시작
/actuator/refresh/ 수동 호출
message가 변경되었다고 응답
메시지 변경 확인!
Config-Server_host/service_name/local로 접속하면 서비스의 설정 값 확인이 가능하다.
오늘의 tmi)
다들 어떻게 4시안에 TIL을 뚝딱 작성하는 거지?
'TIL' 카테고리의 다른 글
[TIL] Zipkin이란? | Redis란? (0) | 2024.08.06 |
---|---|
[TIL] QueryDsl 사용방법 (0) | 2024.08.06 |
[TIL] Java 형변환 | Integer.parseInt와 Integer.valueOf의 차이 | Math.sqrt()와 Math.pow() | 클라이언트 사이드 로드 밸런싱 | 서킷 브레이커 (Resilience4j) | Spring Cloud Gateway (1) | 2024.08.01 |
[TIL] MSA란? | Spring Cloud란? (1) | 2024.07.31 |
[TIL] @Data vs @Getter, @Setter | Building Result란? | CreatedAt UpdatedAt null 해결 (0) | 2024.07.31 |