관리 메뉴

웹개발 블로그

[JWT] API Security and JWT 본문

◆ 인증/JWT

[JWT] API Security and JWT

쿠키린 2024. 10. 25. 00:51

Spring Security

스프링 시큐리티란?

  • 강력한 인증과 권한에 대한 프레임워크
  • REST API를 인증되고 권한이 있는 요청에만 허락해줌.(스프링 시큐리티가 관여함.)

JWT(인증시스템으로 사용)

  • 보안(인증과 권한)에 많이 사용됨
  • JWT(JSON WEB TOKEN) 토큰 형태로 사용됨
    • URL-safe, 웹 브라우저 교환, SSO지원

주요 인증 방식(4가지)

1. 로그인 기반 인증 (크레덴셜 기반 인증)

  • Credential-based authentication
  • 토큰 기반 인증
  • 패스워트를 암호화 해서 받고 

2. 인증 정보를 다른 어플리케이션으로 전달

  • 제 3자가 인증을 처리하는 방식
  • OAuth2 : 다른 인증서비스를 이용하여 현재 애플리케이션 인증하는 방식
  • 페이스북/구글 같은 소셜 계정들을 이용하여 로그인

3. 2단계 인증

로그인이나 토큰으로 1차 인증을 하고 한번 더 인증하는 방식

ex) 핸드폰 인증, 이메일 인증을 통해 보안을 강화하겠다.

 

4.하드웨어 인증

- 패스워드는 암호화된 값을 받아서 처리한다

- 그리고 복호화를 한다던지~

 

서버 기반 인증 시스템 문제점

먼저 JWT 전에 세션에 대해서 먼저 알아보자.

세션

  • 유저가 인증할 때 이 기록을 서버에 저장
    • 유저가 로그인 했을 때 서버에 기록한다는 건 <- 서버 메모리에 정보가 있다는 것
  • 메모리에 저장 혹은 데이터베이스 시스템에 저장
  • 유저의 수(동시 접속)가 많으면 서버나 DB에 부하

확장성

  • 클러스터링 구성 시 세션 정보도 같이 공유해야 함.
    • 클러스터링  : 많은 요청을 받기 위해서 사용
    • 웹 어플리케이션 서버는 기본적으로 이중화가 되어 있으며 클러스팅되어 있다.
  • 각각의 서버에 세션정보가 공유되어야 함. 서버가 확장될때마다 세션 정보도 복제가 되어야한다.
    • 기술을 별도로 사용해야 함.
    • 세션이 복제되야 끊김없이 유지됨.
  • 서버 구성이 복잡해짐

CORS(Cross-Origin Resource Sharing)

  • 쿠키를 여러 도메인에서 관리하는 것이 번거러움
  • 세션을 사용하면 쿠키를 사용하는 여러 도메인에서 관리하기 번거로움.

토큰 기반 인증 시스템 문제

작동원리

  • 유저가 아이디와 비밀번호로 로그인 수행
  • 서버 측에서 해당 정보 검증
  • 계정 정보가 정확하다면 서버측에서 유저(클라이언트)에서 signed 토큰을 발급 - 응답
  • 클라이언트에서는 토큰(긴 문자열 형태) 저장해 두고 요청마다 토큰을 서버에 함께 전달
    • 클라이언트는 토큰을 저장 담당.
  • 이 이후로는 토큰정보와 같이 서버에 요청을 하며, 서버에서 토큰을 검증하고 요청에 응답.
  • 서버는 토큰을 보고 식별함.

토큰은 HTTP 헤더에 포함시켜서 전달

 

토큰을 위조하기는 쉽지 않다.

다만 토큰에 중요한 내용을 넣지 않는다.

토큰 자체에 만료기간을 두어 효율적으로 사용.


토큰 기반 인증 시스템 - 토큰의 장점

  • 무상태이며 확장성 있음
  • 보안성
    • 쿠키를 사용하지 않음.
    • 토큰 환경에서도 취약점은 존재함(보안에 100%는 없음, 누군가 스니핑해서 토큰을 볼 수 있음)
      • 물론 https 스키마 사용 시 해석하기는 쉽지 않음.
      • 토큰은 문자 형
  • 서버 확장이 아닌 기능 확장 가능
    • 토큰 바디부분에 여러가지 데이터를 담을 수 있음.
  • CORS 이슈 해결 - 아무 도메인에서나 토큰만 유효하면 요청이 정상적으로 처리됨
  • 큰 장점 - 웹 표준 기반
    • JWT- 토큰 기반 인증 시스템 구현체(RFC 7519)
    • (중요)토큰의 포맷을 웹 표준으로 공식화 됨.

JSON Web Token

JWT 특징

  • 웹 표준으로 다양한 프로그래밍 언어에서 지원.
  • JSON은 스트링이기때문에 웹에 가장 적합함.
  • Self-contained 필요한 모든 정보를 자체적으로  가지고 있음.
  • 웹 서버의 경우 주로 HTTP 헤더에 넣어서 전달 또는 URL 파라미터로 전달 가능.
    • 단순 스트링으로 이루어진다.

JWT 사용되는 상황

  • 회원인증
  • 정보 교환(인증뿐만 아니라 정보교환으로도 사용됨)

인증뿐만 아니라 정보교환으로도 사용 가능하다.

JWT 구조 - 전체가 스트링(문자)

JWT는 .을 구분자로 3가지 문자열로 구성

헤더(Header) - 두 가지 정보를 포함

  • typ : 토큰의 타입을 지정(JWT)
  • alg : 해싱 알고리즘 지정(HMAC SHA256, RSA ..)
{
    "typ":"JWT",
    "alg":"HS256"
}

 

정보(Payload)

  • 토큰에 담을 정보가 포함(클레임이라고 함, name/value쌍으로 구성)
  • 내용은 Payload에 담는다.

클래임은 다음 세 분류로 나뉨

  • 등록된 클레임 - lss, sub, aud, exp, nbf, sat, jtl
  • 공개 클레임 - 충돌 방지 이름이 필요(주로 URI 형식으로 네이밍)
  • 비공개 클레임 - 클라이언트와 서버 간의 협의 하에 사용되는 크레임
    • 이런 KEY와 이런 DATA를 보낼테니까 받아줘~
    • 주로 비공개 클레임에 필요한 정보들을 담을 수 있다.
{
    "iss": "example.com",
    "exp": "1485279000000",
    "https://example.com/jwt_claims/is_admin": true,
    "userId": "11028373727102",
    "username": "kim"
   
}

 

서명(Signature)

  • 헤더의 내용의 정보를 인코딩하여 남김
  • 이 부분을 확인하여 변조됐는지 알 수 있다.
  • 인코딩 값과 정보의 인코딩 값을 합친 후 주어진 비밀키로 해쉬하여 생성
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3
ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.Sf
lKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

헤더.페이로드.서명 (점 기준)


JWT 토큰 만들기

maven - 디펜던시 설정

<dependency>
  <groupId>javax.xml.bind</groupId>
  <artifactId>jaxb-api</artifactId>
  <version>2.3.1</version>
 </dependency>
 
 <dependency>
  <groupId>io.jsonwebtoken</groupId>
  <artifactId>jjwt</artifactId>
  <version>0.9.1</version>
 </dependency>

 

 

구현

  • 서버에서 발행하고
  • 발행된 토큰을 가지고 클라이언트는 요청하고~
  • 요청 받은 서버에서는 파싱

 

✅토큰 발급받기

 

✅발급받은 TOKEN으로 요청하기

subject가 파싱되어 'ko'가 추출됨.

'◆ 인증 > JWT' 카테고리의 다른 글

인증방식 JWT  (0) 2024.08.07