📂 apiPayload
📂 config
L SecurityConfig
📂 controller
L UserController
📂 domain
L 📂 common
L 📂 enums
L User
📂 dto
L 📂 request
L LoginDto
L 📂 response
L LoginResponseDto
📂 jwt
L JwtFilter
L JwtUtil
📂 repository
L UserRepository
📂 service
L UserService
L UserServiceImpl
🐘 build.gradle
JWT (Json Web Token) 을 처리하기 위한 구현
① JwtFilter : HTTP 요청을 가로채 JWT 토큰을 검증하고, 사용자의 정보를 추출
@RequiredArgsConstructor // final 필드에 대한 생성자를 자동으로 생성합니다.
public class JwtFilter extends OncePerRequestFilter { // 요청당 한 번씩 실행되는 필터를 상속받습니다.
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
final String authorization = request.getHeader(HttpHeaders.AUTHORIZATION); // 요청 헤더에서 Authorization 헤더를 가져옵니다.
logger.info("authorization : " + authorization);
if (authorization == null || !authorization.startsWith("Bearer ")) { // Authorization 헤더가 없거나 "Bearer "로 시작하지 않으면
logger.error("authorization 을 잘못 보냈습니다");
filterChain.doFilter(request, response); // 다음 필터로 요청을 넘기고, 필터 처리를 중지합니다.
return;
}
String token = authorization.split(" ")[1]; // "Bearer " 이후의 실제 JWT 토큰을 추출합니다.
logger.info("token : " + token);
if (JwtUtil.isExpired(token)) { // JWT 토큰이 만료되었는지 확인합니다.
logger.error("Token 이 만료되었습니다");
filterChain.doFilter(request, response); // 만료된 경우, 필터 체인을 계속 진행합니다.
return;
}
String email = JwtUtil.getEmail(token); // JWT에서 이메일을 추출합니다.
logger.info("email: " + email);
// 이메일을 기반으로 인증 객체를 생성하고, SecurityContext에 설정하여 인증된 사용자로 처리합니다.
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(email, null, List.of(new SimpleGrantedAuthority("USER")));
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
filterChain.doFilter(request, response); // 다음 필터로 요청을 넘깁니다.
}
}
② JwtUtil : JWT 토큰을 생성, 검증, 그리고 토큰에서 클레임(이메일 등)을 추출하는 유틸리티 클래스
@Component // Spring Bean으로 등록하여 의존성 주입을 받을 수 있게 합니다.
public class JwtUtil {
@Value("${jwt.secret}")
private String secretKey; // 외부 설정 파일에서 JWT 비밀키를 주입받습니다.
private static SecretKey key; // HMAC-SHA 알고리즘에 사용할 키를 저장합니다.
@PostConstruct
protected void init() {
// 주입받은 비밀키를 Base64로 인코딩한 후, HMAC-SHA 알고리즘에 사용할 SecretKey 객체를 초기화합니다.
secretKey = Base64.getEncoder().encodeToString(secretKey.getBytes());
key = Keys.hmacShaKeyFor(secretKey.getBytes());
}
public static String getEmail(String token) {
// JWT 토큰에서 "email" 클레임을 추출하여 반환합니다.
String res = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token)
.getBody().get("email", String.class);
System.out.println("res: " + res);
return res;
}
public static boolean isExpired(String token) {
// JWT 토큰의 만료 시간을 확인하여, 현재 시간과 비교해 만료되었는지 여부를 반환합니다.
return Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token)
.getBody().getExpiration().before(new Date());
}
public static String createJwt(String email, Long expiredMs) {
// 주어진 이메일과 만료 시간을 사용하여 JWT 토큰을 생성합니다.
Claims claims = Jwts.claims(); // JWT의 클레임(데이터) 객체를 생성합니다.
claims.put("email", email); // 이메일을 클레임에 추가합니다.
return Jwts.builder()
.setClaims(claims) // 클레임을 설정합니다.
.setIssuedAt(new Date(System.currentTimeMillis())) // 토큰이 발급된 시간 설정.
.setExpiration(new Date(System.currentTimeMillis() + expiredMs)) // 만료 시간 설정.
.signWith(key) // 비밀키를 사용해 서명합니다.
.compact(); // JWT 토큰을 생성하여 반환합니다.
}
}
💡 Spring Security 동작 방식
💡 JWT 동작 방식
💡 JWT 인증 과정
💡 JWT 구조
① Header
② Payload
③ Signature
💡 JWT - AccessToken & RefreshToken
L AccessToken : 인증 처리 (클라이언트 저장)
L RefreshToken : AccessToken 재발급 (서버 DB 저장)
📜 jwt 코드 구현 참고 블로그 (감사합니다.....🙏)
https://changha-dev.tistory.com/160
[Spring Boot] Security + jwt로 인증, 인가 구현하기
스프링 시큐리티에서 JWT 토큰 인증 방식을 사용하기 위해서는 다음과 같은 과정을 거칩니다: 사용자 로그인: 클라이언트에서 사용자의 로그인 정보(예: 아이디와 비밀번호)를 서버에 전송합니
changha-dev.tistory.com
https://changha-dev.tistory.com/161
[Spring Boot] jwt로 로그인, 회원가입 API 구현
이전 게시글에서 간단히 loginDto에 username을 입력하면 token을 발급하는 부분을 구현해봤습니다! https://changha-dev.tistory.com/160 [Spring Boot] Security + jwt로 인증, 인가 구현하기 스프링 시큐리티에서 JWT
changha-dev.tistory.com
https://github.com/Changha-dev/jwt-security-v1
GitHub - Changha-dev/jwt-security-v1
Contribute to Changha-dev/jwt-security-v1 development by creating an account on GitHub.
github.com
2024.08.09 - [Spring/[P] AI 기반 사용자 맞춤형 메뉴와 맛집 추천] - [Springboot] 로그인 설계하기
[Springboot] 로그인 설계하기
📂 /user L 회원 가입 L 회원 탈퇴 L 로그인 ⬅️⬅️⬅️ L 로그아웃 L 비밀번호 재설정 (로그인 전) L 비밀번호 재설정 (로그인 후) 🔧 디자인 🔧 필요한 데이터 L email L pas
alsrudalsrudalsrud.tistory.com
[Springboot/SpringSecurity/JWT] 로그인 개발하기 (1) build.gradle, config
📂 apiPayload📂 config L SecurityConfig📂 controller L UserController📂 domain L 📂 common L 📂 enums L User📂 dto L 📂 request L LoginDto L 📂 response L LoginResponseDto📂 jwt L JwtFilter
alsrudalsrudalsrud.tistory.com
'Spring > [P] AI 기반 사용자 맞춤형 메뉴와 맛집 추천' 카테고리의 다른 글
[Springboot/JWT] 로그아웃 설계하기 (0) | 2024.08.19 |
---|---|
[Springboot/SpringSecurity/JWT] 로그인 개발하기 (3) controller, repository, service, dto (1) | 2024.08.16 |
[Springboot/SpringSecurity/JWT] 로그인 개발하기 (1) build.gradle, config (0) | 2024.08.14 |
[Springboot] 로그인 설계하기 (0) | 2024.08.09 |
[Springboot/JWT] 회원 탈퇴 개발하기 (0) | 2024.08.08 |