과정

의존성 추가

스크린샷 2023-12-01 오전 11.32.54.png

Gradle Build

스크린샷 2023-12-01 오후 1.05.24.png

Test 과정

Security 코드

package com.example.demo.src.user.security;

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.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
        http.authorizeHttpRequests(authorize -> authorize
                        .requestMatchers("/").permitAll()
                        .requestMatchers("/setCache/**").hasRole("ADMIN"));
        return http.build();
    }

}

JWT토큰 발행

package com.example.demo.src.user.security;

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

import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.security.InvalidParameterException;
import java.security.Key;
import java.util.Date;

@Component
@NoArgsConstructor
public class JwtTokenProvider {

    // 30분
    private long ACCESS_TOKEN_VALIDATiON_SECOND = 60 * 30;

    // 1개월
    private long REFRESH_TOKEN_VALIDATiON_SECOND = 60 * 60 * 24 * 30;

    private  String secretKey;

    public JwtTokenProvider(String secretKey){
        this.secretKey = secretKey;
    }
    public JwtTokenProvider(
            String secretKey
            , Long accessTokenValidationSecond
            , Long refreshTokenValidationSecond
    ) {
        this.secretKey = secretKey;
        this.ACCESS_TOKEN_VALIDATiON_SECOND = accessTokenValidationSecond;
        this.REFRESH_TOKEN_VALIDATiON_SECOND = refreshTokenValidationSecond;
    }

    private Key getSignKey(String secretKey) {
        byte[] keyBytes = secretKey.getBytes(StandardCharsets.UTF_8);
        return Keys.hmacShaKeyFor(keyBytes);
    }

    // 토큰 해석
    public Claims validTokenAndReturnBody(String token) {
        try {
            return Jwts.parserBuilder()
                    .setSigningKey(getSignKey(secretKey))
                    .build()
                    .parseClaimsJws(token)
                    .getBody();
        } catch(ExpiredJwtException | UnsupportedJwtException | MalformedJwtException | IllegalArgumentException e) {
            e.printStackTrace();
            throw new InvalidParameterException("유효하지 않은 토큰입니다");
        }
    }

    // 유저id 조회
    public String getName(String token) {
        return validTokenAndReturnBody(token).get("username", String.class);
    }

    // 토큰 만료
    private Boolean isTokenExpired(String token){
        Date expiration = validTokenAndReturnBody(token).getExpiration();
        return expiration.before(new Date());
    }

    // access token 생성
    public String generateAccessToken(String username) {
        return doGenerateToken(username, ACCESS_TOKEN_VALIDATiON_SECOND * 1000l);
    }

    // refresh token 생성
    public String generateRefreshToken(String username) {
        return doGenerateToken(username, REFRESH_TOKEN_VALIDATiON_SECOND * 1000l);
    }

    // accessToken 유효시간 알림(second)
    public Long getValidationAccessTokenTime(){
        return ACCESS_TOKEN_VALIDATiON_SECOND;
    }

    private String doGenerateToken(String username, Long expireTime) {
        Claims claims = Jwts.claims();
        claims.put("username", username);

        return Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + expireTime))
                .signWith(getSignKey(secretKey), SignatureAlgorithm.HS256)
                .compact();
    }
}
//
//    private String generateToken(String username, long expirationTimeMillis) {
//        Date now = new Date();
//        Date expirationDate = new Date(now.getTime() + expirationTimeMillis);
//
//        return Jwts.builder()
//                .setSubject(username)
//                .setIssuedAt(now)
//                .setExpiration(expirationDate)
//                .signWith(getSignKey(secretKey), secretKey) // Use RSA 256 algorithm
//                .compact();
//    }
//
//
//
//    public boolean validateToken(String token) {
//        try {
//            Jwts.parserBuilder()
//                    .setSigningKey(secretKey)
//                    .build()
//                    .parseClaimsJws(token);
//            return true;
//        } catch (Exception e) {
//            return false;
//        }
//    }
//
//    public String getUsernameFromToken(String token) {
//        Claims claims = Jwts.parserBuilder()
//                .setSigningKey(secretKey)
//                .build()
//                .parseClaimsJws(token)
//                .getBody();
//        return claims.getSubject();
//    }

스크린샷 2023-12-01 오후 2.03.36.png