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

스프링 부트에서 JWT를 사용한 인증 구현하기

writer_thumbnail

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

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



JWT란 무엇인가?

JWT(JSON Web Token)는 JSON 객체를 사용하여 정보를 안전하게 전송하기 위한 토큰 기반 인증 방식입니다. 왜냐하면 JWT는 클라이언트와 서버 간의 인증 정보를 안전하게 전송할 수 있기 때문입니다.

JWT는 세 부분으로 구성됩니다: 헤더, 페이로드, 서명. 헤더는 토큰의 타입과 해싱 알고리즘을 포함하고, 페이로드는 실제 데이터(클레임)를 포함하며, 서명은 토큰의 무결성을 보장합니다.

JWT는 주로 인증과 권한 부여에 사용됩니다. 왜냐하면 JWT를 사용하면 서버가 클라이언트의 상태를 유지할 필요 없이 클라이언트를 인증할 수 있기 때문입니다.

JWT는 자체적으로 서명되어 있어 변조가 불가능합니다. 왜냐하면 서명이 유효하지 않으면 토큰이 무효화되기 때문입니다.

따라서 JWT는 안전하고 효율적인 인증 방식을 제공합니다.



스프링 부트에서 JWT 설정하기

스프링 부트에서 JWT를 사용하려면 몇 가지 설정이 필요합니다. 왜냐하면 JWT를 사용하기 위해서는 토큰을 생성하고 검증하는 로직이 필요하기 때문입니다.

먼저, JWT 라이브러리를 추가해야 합니다. Maven을 사용하는 경우, pom.xml 파일에 다음과 같이 의존성을 추가합니다.


    io.jsonwebtoken
    jjwt
    0.9.1

그 다음, JWT 토큰을 생성하고 검증하는 유틸리티 클래스를 작성합니다. 예를 들어, JwtTokenProvider 클래스를 작성하여 토큰을 생성하고 검증하는 메서드를 구현할 수 있습니다.

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.stereotype.Component;
import java.util.Date;

@Component
public class JwtTokenProvider {

    private final String SECRET_KEY = "mySecretKey";
    private final long EXPIRATION_TIME = 86400000; // 1 day

    public String createToken(String username) {
        Claims claims = Jwts.claims().setSubject(username);
        Date now = new Date();
        Date validity = new Date(now.getTime() + EXPIRATION_TIME);
        return Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(now)
                .setExpiration(validity)
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
    }

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

    public boolean validateToken(String token) {
        try {
            Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

위 예제는 JWT 토큰을 생성하고 검증하는 기본적인 로직을 포함합니다. 왜냐하면 JWT를 사용하여 클라이언트를 인증하기 위해서는 이러한 로직이 필요하기 때문입니다.



JWT를 사용한 인증 필터 구현하기

스프링 부트에서 JWT를 사용한 인증 필터를 구현하려면, JwtAuthenticationFilter 클래스를 작성해야 합니다. 왜냐하면 JWT 토큰을 검증하고, 유효한 토큰인 경우 인증 객체를 생성하여 SecurityContext에 저장해야 하기 때문입니다.

다음은 JwtAuthenticationFilter 클래스의 예제입니다.

import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
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 {

    private final JwtTokenProvider jwtTokenProvider;
    private final UserDetailsService userDetailsService;

    public JwtAuthenticationFilter(JwtTokenProvider jwtTokenProvider, UserDetailsService userDetailsService) {
        this.jwtTokenProvider = jwtTokenProvider;
        this.userDetailsService = userDetailsService;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = resolveToken(request);
        if (token != null && jwtTokenProvider.validateToken(token)) {
            String username = jwtTokenProvider.getUsername(token);
            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
            if (userDetails != null) {
                JwtAuthenticationToken authentication = new JwtAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }
        filterChain.doFilter(request, response);
    }

    private String resolveToken(HttpServletRequest request) {
        String bearerToken = request.getHeader("Authorization");
        if (bearerToken != null && bearerToken.startsWith("Bearer ")) {
            return bearerToken.substring(7);
        }
        return null;
    }
}

위 예제는 JWT 토큰을 검증하고, 유효한 토큰인 경우 인증 객체를 생성하여 SecurityContext에 저장하는 로직을 포함합니다. 왜냐하면 JWT를 사용한 인증을 구현하기 위해서는 이러한 필터가 필요하기 때문입니다.



스프링 시큐리티 설정

스프링 부트에서 JWT를 사용한 인증을 구현하려면, 스프링 시큐리티 설정이 필요합니다. 왜냐하면 스프링 시큐리티를 통해 인증 필터를 등록하고, 인증 및 권한 부여를 설정해야 하기 때문입니다.

다음은 스프링 시큐리티 설정 클래스의 예제입니다.

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 {

    private final JwtTokenProvider jwtTokenProvider;

    public SecurityConfig(JwtTokenProvider jwtTokenProvider) {
        this.jwtTokenProvider = jwtTokenProvider;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            .antMatchers("/api/auth/**").permitAll()
            .anyRequest().authenticated()
            .and()
            .addFilterBefore(new JwtAuthenticationFilter(jwtTokenProvider, userDetailsService()), UsernamePasswordAuthenticationFilter.class);
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return new CustomUserDetailsService();
    }
}

위 예제는 스프링 시큐리티 설정을 통해 JWT 인증 필터를 등록하고, 인증 및 권한 부여를 설정하는 로직을 포함합니다. 왜냐하면 스프링 시큐리티를 통해 인증 및 권한 부여를 설정해야 하기 때문입니다.



결론

JWT는 안전하고 효율적인 토큰 기반 인증 방식을 제공합니다. 왜냐하면 JWT는 클라이언트와 서버 간의 인증 정보를 안전하게 전송할 수 있기 때문입니다.

스프링 부트에서 JWT를 사용하여 인증을 구현하려면, JWT 토큰을 생성하고 검증하는 로직과 인증 필터를 구현해야 합니다. 왜냐하면 JWT를 사용한 인증을 구현하기 위해서는 이러한 로직이 필요하기 때문입니다.

스프링 시큐리티 설정을 통해 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