[JWT] JWT(Json Web Token)이란? + Spring Boot에서 구현하기
A A

 

JWT(Json Web Token)은 사용자 인증, 데이터 교환에 사용되는 토큰 기반 인증 방식

즉,

서버-클라이언트 간의 보안 인증서 역할을 함.

 


 

JWT란?

JSON 형식으로 구성된, 3부분으로 이루어진 문자열.

  1. Header: 토큰의 타입, 알고리즘 정보 포함
  2. Payload: 토큰에 포함된 데이터(사용자 ID, 권한 정보 등)
  3. Signature: 토큰의 무결성을 검증하기 위한 서명
예:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIxMjMiLCJleHAiOjE2NzQ5NjM4MDB9.dXN3iQjXryGvQo_rivmnDNfQnMJy9Q0hDIpg9hswKmA

 

 

 


JWT를 활용한 로그인 호출

 

1. 사용자 로그인 요청

- 사용자가 아이디, 비밀번호를 입력하고 로그인 요청을 보냄.

2. 서버에서 인증 후, JWT 발급

- 서버는 DB에서 사용자 정보를 확인하고, 인증 성공시 JWT 생성함.

- 이 JWT는 사용자 정보를 암호화하고, 클라이언트로 반환함.

3. 클라이언트가 JWT 저장

- 클라이언트(앱)은 반환된 JWT를 로컬 스토리지 or 세션에 저장함.

4. 추후 요청에 JWT 포함

- 클라이언트는 서버에 요청할 때마다 Header에 JWT를 포함하여 인증을 진행함.

5. 서버가 JWT 검증

- 서버는 JWT가 변조되지 않았는지 확인하고, 유효 기간이 남아있으면 요청을 처리함.

 


 

 

Spring Boot에서 JWT 구현하기

 

1. JWT 라이브러리 추가

<!-- build.gradle.kts -->
implementation("io.jsonwebtoken:jjwt-api:0.11.5")
runtimeOnly("io.jsonwebtoken:jjwt-impl:0.11.5")
runtimeOnly("io.jsonwebtoken:jjwt-jackson:0.11.5")

 

2. 토큰 생성 및 검증 클래스

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;

import java.security.Key;
import java.util.Date;

public class JwtUtil {

    private static final String SECRET_KEY = "your-256-bit-secret-key"; // 환경 변수로 관리 권장
    private static final Key key = Keys.hmacShaKeyFor(SECRET_KEY.getBytes());
    private static final long EXPIRATION_TIME = 1000 * 60 * 60; // 1시간

    // 토큰 생성
    public static String generateToken(String userId) {
        return Jwts.builder()
                .setSubject(userId)
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(key, SignatureAlgorithm.HS256)
                .compact();
    }

    // 토큰 검증
    public static String validateToken(String token) {
        try {
            Claims claims = Jwts.parserBuilder()
                    .setSigningKey(key)
                    .build()
                    .parseClaimsJws(token)
                    .getBody();
            return claims.getSubject();
        } catch (JwtException e) {
            return null; // 유효하지 않은 토큰
        }
    }
}

 

3. 로그인 컨트롤러 

@RestController
@RequestMapping("/auth")
public class AuthController {

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody LoginRequest loginRequest) {
        // 사용자를 데이터베이스에서 인증 (여기서는 생략)
        String userId = "exampleUser"; // 인증된 사용자 ID

        // JWT 생성
        String token = JwtUtil.generateToken(userId);

        return ResponseEntity.ok(new LoginResponse(token));
    }

    @GetMapping("/secure")
    public ResponseEntity<?> secureEndpoint(@RequestHeader("Authorization") String authHeader) {
        // JWT 검증
        String token = authHeader.replace("Bearer ", "");
        String userId = JwtUtil.validateToken(token);

        if (userId == null) {
            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
        }

        return ResponseEntity.ok("Secure data for user: " + userId);
    }
}

 

 

 

Copyright 2024. GRAVITY all rights reserved