개발/전자정부프레임워크

전자정부프레임워크에서 JWT(Json Web Token) 기반 인증 구현

꿈꾸는법사 2024. 12. 28. 19:40
반응형

오늘은 전자정부프레임워크 프로젝트에서 **JWT(Json Web Token)**를 사용하여 인증을 구현하는 방법을 배워보겠습니다. JWT는 사용자 인증 정보를 안전하게 저장하고 stateless한 방식으로 API 인증을 처리할 수 있는 효율적인 방법입니다.


1. JWT란?

**JWT(Json Web Token)**는 JSON 객체를 사용하여 사용자 정보를 안전하게 전달하는 토큰 기반 인증 방식입니다.
JWT는 크게 세 부분으로 구성됩니다:

  1. Header: 토큰 타입과 암호화 알고리즘 정보
  2. Payload: 사용자 정보 및 클레임(claim)
  3. Signature: 토큰의 무결성을 검증하는 서명

JWT는 클라이언트와 서버 간 상태를 유지하지 않기 때문에 stateless 인증을 지원합니다.


2. JWT 구현 준비

2-1. 의존성 추가

pom.xml 파일에 JWT를 생성 및 검증하기 위한 의존성을 추가합니다.

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.5</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.5</version>
</dependency>

3. JWT 유틸리티 클래스 작성

JWT 생성 및 검증 로직을 처리하는 클래스를 작성합니다.

JwtUtil.java

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.Claims;

import java.util.Date;

public class JwtUtil {

    private static final String SECRET_KEY = "my-secret-key";
    private static final long EXPIRATION_TIME = 1000 * 60 * 60; // 1시간

    // JWT 생성
    public static String generateToken(String username) {
        return Jwts.builder()
                .setSubject(username)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }

    // JWT 검증 및 사용자 이름 추출
    public static String validateToken(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody();
        return claims.getSubject();
    }
}

4. JWT를 활용한 인증 API 구현

4-1. 로그인 API

사용자가 로그인하면 JWT를 발급합니다.

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
public class AuthController {

    @PostMapping("/api/login")
    public String login(@RequestBody Map<String, String> credentials) {
        String username = credentials.get("username");
        String password = credentials.get("password");

        // 예시: 간단한 사용자 인증
        if ("user".equals(username) && "password".equals(password)) {
            return JwtUtil.generateToken(username);
        } else {
            throw new RuntimeException("Invalid credentials");
        }
    }
}

4-2. 인증된 API

JWT를 검증하여 인증된 사용자만 접근할 수 있는 API를 작성합니다.

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SecureApiController {

    @GetMapping("/api/secure/data")
    public String getSecureData(@RequestHeader("Authorization") String token) {
        // "Bearer " 접두사 제거
        token = token.replace("Bearer ", "");
        String username = JwtUtil.validateToken(token);
        return "Hello, " + username + "! This is a secure message.";
    }
}

5. Postman으로 테스트하기

5-1. 로그인 API 호출

  1. URL: http://localhost:8080/api/login
  2. Method: POST
  3. Body: JSON 형식
    {
        "username": "user",
        "password": "password"
    }
    
  4. 응답: JWT 토큰 반환

5-2. 인증된 API 호출

  1. URL: http://localhost:8080/api/secure/data
  2. Method: GET
  3. Header:
    • Key: Authorization
    • Value: Bearer <발급받은 JWT 토큰>
  4. 응답: 인증 성공 시 사용자 이름 포함 메시지 반환

6. 추가 보안 고려사항

  1. 토큰 만료 처리: 만료된 토큰은 클라이언트가 갱신 요청을 해야 합니다.
  2. HTTPS 사용: 네트워크 상에서 토큰이 탈취되지 않도록 HTTPS로 통신을 암호화합니다.
  3. 토큰 무효화: 사용자가 로그아웃하거나 토큰이 탈취된 경우, 토큰을 무효화하는 로직이 필요합니다.

7. 마무리

오늘은 전자정부프레임워크에서 JWT를 사용한 인증 구현 방법을 알아보았습니다. 다음 시간에는 JWT와 Spring Security를 연동하는 방법을 다뤄보겠습니다.

반응형