F-Lab
🚀
상위권 IT회사 합격 이력서 무료로 모아보기

스프링 부트와 JWT를 이용한 인증 구현

writer_thumbnail

F-Lab : 상위 1% 개발자들의 멘토링

AI가 제공하는 얕고 넓은 지식을 위한 짤막한 글입니다!



스프링 부트와 JWT를 이용한 인증 구현

안녕하세요. 오늘은 스프링 부트와 JWT(Json Web Token)를 이용한 인증 구현에 대해 다뤄보겠습니다. 왜냐하면 JWT는 현대 웹 애플리케이션에서 널리 사용되는 인증 방식이기 때문입니다.

JWT는 JSON 객체를 사용하여 정보를 안전하게 전송하는 방식입니다. 이 정보는 디지털 서명되어 있어, 수신자가 정보의 무결성을 확인할 수 있습니다. JWT는 주로 사용자 인증 및 권한 부여에 사용됩니다.

스프링 부트는 자바 기반의 애플리케이션을 빠르게 개발할 수 있는 프레임워크입니다. 스프링 부트와 JWT를 결합하면, 강력하고 확장 가능한 인증 시스템을 구축할 수 있습니다.

이번 글에서는 스프링 부트와 JWT를 이용한 인증 시스템을 단계별로 구현해보겠습니다. 왜냐하면 이론만으로는 이해하기 어렵기 때문입니다.

그럼 시작해보겠습니다.



JWT의 기본 개념

JWT는 세 부분으로 구성됩니다: 헤더, 페이로드, 서명. 왜냐하면 이 세 부분이 JWT의 핵심 요소이기 때문입니다.

헤더는 토큰의 타입과 해싱 알고리즘을 포함합니다. 예를 들어, 토큰의 타입은 JWT이고, 해싱 알고리즘은 HMAC SHA256일 수 있습니다.

페이로드는 토큰에 포함된 클레임(Claim)을 담고 있습니다. 클레임은 사용자 정보, 만료 시간 등의 데이터를 포함할 수 있습니다.

서명은 헤더와 페이로드를 인코딩한 후, 비밀 키를 사용하여 생성됩니다. 서명은 토큰의 무결성을 보장합니다.

JWT는 Base64Url로 인코딩되어 전송됩니다. 수신자는 이 토큰을 디코딩하여 정보를 확인할 수 있습니다.



스프링 부트 프로젝트 설정

먼저, 스프링 부트 프로젝트를 생성하고 필요한 의존성을 추가하겠습니다. 왜냐하면 프로젝트 설정이 첫 번째 단계이기 때문입니다.

스프링 부트 프로젝트를 생성하려면, Spring Initializr를 사용할 수 있습니다. Spring Initializr 웹사이트에서 프로젝트를 생성하고, 필요한 의존성을 선택합니다.

이번 프로젝트에서는 Spring Web, Spring Security, JWT 라이브러리를 사용할 것입니다. 아래는 build.gradle 파일의 예제입니다.

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'io.jsonwebtoken:jjwt:0.9.1'
}

위 코드에서 필요한 의존성을 추가하였습니다. 이제 프로젝트를 빌드하고, 필요한 설정을 진행하겠습니다.

스프링 부트 애플리케이션의 진입점인 Application 클래스를 생성합니다.

@SpringBootApplication
public class JwtApplication {
    public static void main(String[] args) {
        SpringApplication.run(JwtApplication.class, args);
    }
}

위 코드에서 @SpringBootApplication 어노테이션을 사용하여 스프링 부트 애플리케이션을 설정하였습니다.



JWT 토큰 생성 및 검증

이제 JWT 토큰을 생성하고 검증하는 코드를 작성해보겠습니다. 왜냐하면 JWT의 핵심 기능이 토큰 생성과 검증이기 때문입니다.

먼저, JWT 토큰을 생성하는 유틸리티 클래스를 작성합니다.

import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;

public class JwtTokenUtil {
    private static final String SECRET_KEY = "mySecretKey";

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

    public static String validateToken(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody()
                .getSubject();
    }
}

위 코드에서 generateToken 메소드는 사용자 이름을 받아 JWT 토큰을 생성합니다. validateToken 메소드는 토큰을 검증하고, 사용자 이름을 반환합니다.

이제 JWT 토큰을 이용한 인증 필터를 작성합니다.

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = request.getHeader("Authorization");
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            String username = JwtTokenUtil.validateToken(token);
            if (username != null) {
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, null, null);
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }
        filterChain.doFilter(request, response);
    }
}

위 코드에서 JwtAuthenticationFilter 클래스는 HTTP 요청을 가로채 JWT 토큰을 검증합니다. 토큰이 유효하면, 사용자 정보를 SecurityContext에 설정합니다.



스프링 시큐리티 설정

이제 스프링 시큐리티 설정을 진행하겠습니다. 왜냐하면 스프링 시큐리티를 통해 인증과 권한 부여를 관리할 수 있기 때문입니다.

스프링 시큐리티 설정 클래스를 작성합니다.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Bean
    public JwtAuthenticationFilter jwtAuthenticationFilter() {
        return new JwtAuthenticationFilter();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            .antMatchers("/login").permitAll()
            .anyRequest().authenticated()
            .and()
            .addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
    }
}

위 코드에서 @EnableWebSecurity 어노테이션을 사용하여 스프링 시큐리티를 활성화하였습니다. configure 메소드에서 JWT 인증 필터를 추가하고, 세션 관리를 Stateless로 설정하였습니다.

이제 로그인 엔드포인트를 구현해보겠습니다.

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

@RestController
public class AuthController {
    @PostMapping("/login")
    public String login(@RequestBody User user) {
        // 사용자 인증 로직 (생략)
        return JwtTokenUtil.generateToken(user.getUsername());
    }
}

위 코드에서 /login 엔드포인트를 통해 사용자 인증을 수행하고, JWT 토큰을 반환합니다.



결론

오늘은 스프링 부트와 JWT를 이용한 인증 구현에 대해 다뤄보았습니다. 왜냐하면 JWT는 현대 웹 애플리케이션에서 널리 사용되는 인증 방식이기 때문입니다.

스프링 부트와 JWT를 결합하면, 강력하고 확장 가능한 인증 시스템을 구축할 수 있습니다. 이번 글에서 다룬 내용들을 실제 프로젝트에 적용해보시기 바랍니다.

다음 글에서는 더 심화된 내용을 다뤄보겠습니다. 많은 기대 부탁드립니다.

감사합니다.

ⓒ F-Lab & Company

이 컨텐츠는 F-Lab의 고유 자산으로 상업적인 목적의 복사 및 배포를 금합니다.

조회수
F-Lab
소개채용멘토 지원
facebook
linkedIn
youtube
instagram
logo
(주)에프랩앤컴퍼니 | 사업자등록번호 : 534-85-01979 | 대표자명 : 박중수 | 전화번호 : 1600-8776 | 제휴 문의 : info@f-lab.kr | 주소 : 서울특별시 강남구 테헤란로63길 12, 438호 | copyright © F-Lab & Company 2025