[SpringBoot3] JWT 토큰 서비스

yoons(이윤서)·2024년 9월 4일
post-thumbnail

👉🏻 이 글은 <스프링부트3 백엔드 개발자 되기-자바편(2판)>의 9장을 공부하며 작성한 글입니다.


JWT (Json Web Token) : 웹 표준을 따르며 JSON 객체를 사용하여 정보를 전달한다. 토큰 기반의 인증 방법을 사용한다.

📌 토큰 기반 인증


사용자가 서버에 접근할 때 사용자가 인증된 사용자인지 확인하는 방법 두 가지

1. 서버 기반 인증

  • 세션 기반 인증 : 스프링 시큐리티
    기본적으로 제공해주는 세션 기반 인증을 사용해 사용자마다 사용자의 정보를 담은 세션을 생성하고 서버의 세션 저장소에 저장해서 인증을 함.

    세션 개념 참고 : (https://hudi.blog/cookie-and-session/)

2. 토큰 기반 인증

  • 토큰: 서버에서 클라이언트를 구분하기 위한 유일한 값
    서버가 토큰을 생성래서 클라이언트에게 제공
    -> 클라이언트는 이 토큰을 가지고 있다가 여러 토큰과 함께 신청
    -> 서버가 유효한 사용자인지 검증

📖 토큰을 전달하고 인증받는 과정

책의 내용을 위와 같이 그림으로 정리함.


📖 토큰 기반 인증의 특징

  • 무상태성

    무상태성은 사용자의 인증 정보가 담겨 있는 토큰이 서버가 아닌 클라이언트에 있으므로 서버에 저장할 필요가 없는 것이다.
    즉, 클라이언트가 토큰을 생성하고 인증, 인증 상태를 유지하면서 요청 처리(=상태 관리) 하므로 서버 입장에서는 클라이언트의 인증정보를 저장하거나 유지하지 않아도 되기 때문에 완전한 무상태로 효율적인 검증이 가능하다.

  • 확장성

    서버를 확장할 때 상태 관리를 신경 쓸 필요가 없으니(무상태성) 서버 확장에도 용이한 것이다. 세션 기반 인증은 각각 API에서 인증을 해야되는 것과는 달리 토큰 기반 인증에서는 토큰을 가지는 주체는 서버가 아닌 클라이언트이기 때문에 가지고 있는 하나의 토큰으로 결제 서버와 주문 서버에 요청을 보낼 수 있다. 추가로 다른 토큰 기반 인증을 사용하는 다른 시스템에 접근해 로그인 방식을 확장할 수도 있고, 다른 서비스에 권한을 공유할 수도 있다.

  • 무결성

    토큰 방식은 HMAC(hash-based message authenticarion)이라고도 부르는데, 토큰을 발급한 이후에는 토큰 정보를 변경하는 행위를 할 수 없다. 즉, 토큰의 무결성이 보장되는 것이다. 만약 누군가 토큰을 변경한다면 서버에서는 유효하지 않은 토큰으로 판단한다.

📌 JWT

발급받은 JWT를 이용해 인증을 하려면 HTTP 요청 헤더 중, Authorization 키값에 Bearer + JWT 토큰값 을 넣어 보내야 합니다.

📖 JWT의 구조

JWT는 .을 기준으로 헤더(header) / 내용(payload) / 서명(signature) 으로 이루어져 있습니다.

- 토큰 생성 메서드 예시

TokenProvider.java - makeToken 메서드

// JWT 토큰 생성 메서드
private String makeToken(Date expiry, User user){
    Date now = new Date();
        
    // JWT = 헤더.내용.서명
    return Jwts.builder()
            // 헤더 typ : JWT
            .setHeaderParam(Header.TYPE, Header.JWT_TYPE) 
            // 내용 iss : ajufresh@gmail.com(propertise 파일에서 설정한 값)
            .setIssuer(jwtProperties.getIssuer())
            .setIssuedAt(now)   // 내용 iat : 현재 시간
            .setExpiration(expiry)  // 내용 exp : expiry 멤버 변숫값
            .setSubject(user.getEmail())    // 내용 sub : 유저의 이메일
            .claim("id", user.getId())  // 클레임 id : 유저 ID
            // 서명 : 비밀값과 함께 해시값을 HS256 방식으로 암호화
            .signWith(SignatureAlgorithm.HS256, jwtProperties.getSecretKey())
            .compact();
}

📖 토큰 유효기간

❓ 만약 토큰 자체가 노출된다면? 토큰은 이미 발급되면 그 자체로 인증 수단이 되므로 서버는 토큰과 함께 들어온 요청이 토큰을 탈취한 사람의 요청인지 확인할 수 없다.

리프레시 토큰
보안을 위해서는 토큰의 유효기간이 짧으면 되겠지만, 토큰의 유효기간이 너무 짧으면 사용자 입장에서는 불편할 수 있다.

➡️ 액세스 토큰의 유효기간을 짧게 하고, 리프레시 토큰의 유효기간을 길게 설정!

리프레시 토큰은 액세스 토큰과 별개로 액세스 토큰이 만료되었을 때 새로운 액세스 토큰을 발급하기 위해 사용한다.

📖 액세스 토큰과 리프레시 토큰 전달 & 인증 과정


이를 이해하고 JWT 서비스를 구현하면 됨.

profile
개발공부하는 잠만보

0개의 댓글