Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

이지은님의 블로그

250226 - Java Spring 인증과 인가, Session, JWT인증 방식(Secret Key, generateToken, validateToken) 본문

TIL

250226 - Java Spring 인증과 인가, Session, JWT인증 방식(Secret Key, generateToken, validateToken)

queenriwon3 2025. 2. 26. 16:19

▷ 오늘 배운 것

인증과 인가에 대한 내용과 더불어 지난 프로젝트에 적용하지 못했던 jwt를 session인증과 비교해 보면서 공부해보겠다.

 

<<목차>>

1. 인증과 인가

    1) 인증 (Authentication)

    2) 인가 (Authorization)

2. Session 방식과 JWT 방식

    1) Session 방식 (기존 인증 방식)

    2) JWT 방식 (토큰 기반 방식)

    3) JSON Web Token (JWT)

    4) 세션 기반 인증 방식과 JWT 인증 방식

    5) JWT 구현을 위한 요소

 

 

 


 

1. 인증과 인가

1) 인증(Authentication)

: 인증은 “신원을 확인하는 과정”이다.

 

인증이 필요한 이유
  1. 사용자를 식별하기 위해: 서비스가 어떤 사용자가 접속했는지 확인함으로 맞춤형 서비스를 제공
  2. 추적 가능하도록 만들기 위해: 사용자의 활동이력 남김
  3. 보안을 위해: 내 것이 맞는지 확인해야 악의적인 접근을 막을 수 있음
인증을 위해 필요한 것
  1. 아이디 / 이메일 주소 (사용자를 식별하는 유니크한 값)
  2. 비밀번호 (사용자가 본인임을 증명
  3. 추가적인 보안요소 (OTP, 보안 질문, 생체 인식 등)

 

 

2) 인가(Authorization)

: 인가는 인증된 사용자가 “특정 리소스에 접근할 수 있는 권한을 확인하는 과정”이다.

관리자 페이지를 제한하거나, 게시판의 수정/삭제 버튼 활성화 여부, 구독서비스의 프리미엄 기능을 제한 하는 등에서 주로 사용된다.

 

인가가 필요한 이유
  1. 역할에 따라 다른 권한을 부여하기 위해: 관리자, 일반 사용자, 게스트 등 역할에 따라 접근 가능한 기능이 다름
  2. 보안을 강화하기 위해: 모든 사용자가 모든 데이터에 접근할 수 있으면 보안 문제가 발생함.
인가를 적용하는 방식

1️⃣ RBAC(Role-Based Access Control)

: 역할(role)을 기준으로 권한을 부여(예: 관리자, 일반 사용자, 게스트)

2️⃣ ABAC(Attribute-Based Access Control)

: 특정 속성(Attribute)을 기준으로 권한을 부여하는 방식 (예: 나이, 위치, 시간 등)

 

 

인증 VS 인가


인증(Authentication) 인가(Authorization)
개념 사용자가 본인이 맞음을 증명 사용자가 특정 리소스에 접근할 있는지 확인하는 과정
예시 로그인 성공 여부 관리자 페이지 접근 제한
필요 요소 아이디, 비밀번호, 이메일, 핸드폰 번호 등등 역할(Role), 권한(Privileges)
적용 시점 로그인 시점 로그인 이후

 

 

 

2. Session 방식과 JWT 방식

1) Session 방식(기존 인증 방식)

  • 인증 성공시 서버가 세션ID를 발급하여 클라이언트에 저장
  • 서버는 세션 ID를 관리하면서 사용자 정보 유지
  • 클라이언트는 요청시 세션 ID를 포함하며 서버로 보낸다.

—> 단점: 세션 관련으로 서버 관리 부담, 로드 밸런싱환경에서 세션을 공유하기 어려워 분산 시스템에서 사용하기 어려움

 

(예시- 인스타그램)

세션 기반 인증을 사용하면 로그인시 세션 쿠키를 발급하고, 쿠키를 통해 인증을 유지할 수 있다. 사용자가 비밀번호를 변경하면 기존세션 자동 만료

세션을 이용하면 계정을 여러기기에서 동시에 로그인 가능, 안전한 강제 로그아웃 기능이 가능(모든 기기에서 로그아웃)

==>(서버 확장이 가능하다면) 로그인이 중요한 서비스는 세션 기반 로그인 선호

 

 

2) JWT 방식(토큰 기반 방식)

  • 인증 성공 시 서버가 JWT를 발급하여 클라이언트에 저장
  • 클라이언트는 이후 요청 시 JWT를 포함하여 서버로 보냄
  • 서버는 JWT를 검증하여 사용자를 확인 (세션 저장 불필요)

—> 장점: 무상태성 (stateless) 유지 가능하기 때문에 서버 확장성, 로드 밸런싱과 분산시스템 적합

     빠른 인증과 검증, 다른 서비스에도 인증 공유 가능(SSO: 한번의 로그인으로 여러개에 서비스에 접근할 수 있는 인증 방식)

—> 단점: 토큰의 길이가 길어 네트워크 부하, 탈취시 보안문제(-> HTTPS 사용, 짧은 만료 시간 설정, Refresh Token 활용)

 

(예시 - 구글)

구글의 OAuth2 로그인에서 Access Token, ID Token이 JWT 형식으로 발급됨.

JWT 기반 인증이므로, 서버가 사용자 세션을 관리할 필요 없음. 마이크로서비스 아키텍처(MSA)에 적합함. ID Token은 클라이언트에서 디코딩하여 사용자 정보를 확인 가능.

 

마이크로서비스 아키텍처(MSA)란?
하나의 애플리케이션을 작은 독립적인 서비스들로 나누어 구성하는 방식
각 서비스를 독립적으로 다루며, 서로 API로 소통한다.

이러한 구조는 대규모 시스템 및 운영에 유리하며(언어 기술 스택을 다양하게 사용 가능), 확장성과 유지보수성이 뛰어나고 장애 격리가 가능하다는 장점이 있다.
운영 복잡성이 증가하고 데이터 일관성에 대해 트랜잭션관리가 어렵다. 그리고 서비스간 API 통신이 많아지며 네트워크 비용이 증가 한다.

 

 

3) JSON Web Token(JWT)

: 인증 정보를 포함하는 JSON 기반 토큰이다. 사용자의 정보(Claims)를 포함하는 디지털 서명된 문자열로 구성된다.

구조 설명
Header 알고리즘 정보(alg: HS256, RS256 )
Payload 사용자 정보(sub, exp, roles )
Signature Header + Payload 기반으로 생성된 서명

 

 

4) 세션 기반 인증 방식과 JWT 인증 방식

세션 기반 인증 방식 JWT 인증 방식
1️⃣ 로그인을 하면 특정 서버에서 세션을 생성
2️⃣ 서버는 생성된 정보를 메모리에 저장
3️⃣ 클라이언트는 요청시 세션ID 쿠키에 담아 서버로 보냄
4️⃣ 세션 ID 저장된 서버로 연결되면 정상 인증
1️⃣ 로그인을 하면, 서버가 JWT 생성하여 클라이언트에 전달
2️⃣ 클라이언트는 요청할 JWT 포함하여 요청
3️⃣ 요청받은 서버는 JWT 검증하여 인증 수행
해당 서버에만 세션이 저장되는 문제점
->
서버가 바뀔 때마다 로그인 상태가 유지되지 않거나 세션이 없는 문제
모든 서버가 동일한 secret key 사용하여 jwt검증
->
어떤 서버로 가더라도 로그인 상태 유지 가능

 

 

5) JWT 구현을 위한 요소

1️⃣ JWT Secret Key (서명에 사용)

  • JWT는 서버에서 서명(Signature)을 생성하여 변조되지 않도록 보장해야 함
  • HMAC(SHA256)이나 RSA 서명을 사용할 수 있으며, 서버에서 Secret Key를 안전하게 관리해야 함.
  • Secret Key 환경 변수(Environment Variable) 관리하는 것이 보안적으로 안전함.

=> secret key 환경변수로 관리

=> signature 키를 초기화 하는 역할

=> Base64로 인코딩된 secretKey를 디코딩하여, HMAC-SHA 알고리즘에 적합한 키(key)로 변환(보안키 생성)

 

 

2️⃣ JWT 토큰 생성 (generateToken)

로그인 성공 사용자 정보를 담은 JWT 토큰(Access Token) 생성해야

  • setSubject() → 사용자 식별 값(userId 또는 email)
  • setExpiration(Date(...)) → 만료 시간 지정 (+1시간)
  • signWith(HS256, SECRET_KEY.toByteArray()) → HMAC SHA256 알고리즘으로 서명(signature)

 

 

3️⃣ JWT 검증 (validateToken)

요청이 들어올 JWT 유효한지 검증하는 과정

=> 토큰을 파싱하고, 추출하는 메서드

 

claims.expiration.after(Date()) → 만료 여부 체크

SignatureException → 서명이 조작되었는지 확인

등 검증하는 로직이 추가적으로 필요하다.

 

 

4️⃣ JWT에서 사용자 정보 추출 (getUsernameFromToken)

  • JWT에서 사용자 정보를 가져오는 기능 필요
  • 토큰을 해석하여 subject(사용자 ID 또는 이메일) 추출함.

 

 

5️⃣ JWT를 HTTP 요청 필터에서 검증(이후 Spring Security)

  • Spring Security에서 OncePerRequestFilter를 사용하여 모든 요청에서 JWT를 검증하도록 설정.
  • 요청에서 Authorization: Bearer <TOKEN> 헤더를 가져와서 토큰을 추출.
  • validateToken(token) → 토큰 검증.
  • getUsernameFromToken(token) → 사용자 정보 추출.