Skip to content

Commit

Permalink
✨ 기능 추가 :RedisService logout시 쿠키 삭제 및 redis 삭제 기능 추가
Browse files Browse the repository at this point in the history
✨ 기능 추가 :RedisService logout시 쿠키 삭제 및 redis 삭제 기능 추가
  • Loading branch information
sksmsdlskgus authored Nov 29, 2024
2 parents c061cd2 + 3aefc8e commit 71d5a86
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
import intbyte4.learnsmate.admin.mapper.AdminMapper;
import intbyte4.learnsmate.admin.service.AdminService;
import intbyte4.learnsmate.admin.service.EmailService;
import intbyte4.learnsmate.admin.service.RedisService;
import intbyte4.learnsmate.common.exception.CommonException;
import intbyte4.learnsmate.common.exception.StatusEnum;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -38,6 +40,7 @@ public class AdminController {
private final AdminService adminService;
private final AdminMapper adminMapper;
private final EmailService emailService;
private final RedisService redisService;

@Operation(summary = "직원 단건 조회")
@GetMapping("/{adminCode}")
Expand Down Expand Up @@ -74,16 +77,41 @@ public ResponseEntity<Map<String, Object>> checkAuthStatus(@AuthenticationPrinci

@Operation(summary = "직원 로그아웃")
@PostMapping("/logout")
public ResponseEntity<?> logout(HttpServletResponse response) {
public ResponseEntity<?> logout(HttpServletRequest request,HttpServletResponse response) {
log.info("POST /admin/logout 요청 도착");
// 쿠키 삭제 명령
Cookie cookie = new Cookie("token", null);
cookie.setPath("/");
cookie.setHttpOnly(true);
cookie.setMaxAge(0); // 쿠키 만료 처리
response.addCookie(cookie);

// 필요 시 블랙리스트로 JWT 관리

// 쿠키에서 refreshToken 추출
String refreshToken = null;

// 쿠키에서 refreshToken 추출
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if ("refreshToken".equals(cookie.getName())) {
refreshToken = cookie.getValue();
}
}
}

// 쿠키 삭제
Cookie accessTokenCookie = new Cookie("accessToken", null);
accessTokenCookie.setPath("/");
accessTokenCookie.setHttpOnly(true);
accessTokenCookie.setMaxAge(0); // 쿠키 만료 처리 (브라우저에서 삭제됨)
response.addCookie(accessTokenCookie);

Cookie refreshTokenCookie = new Cookie("refreshToken", null);
refreshTokenCookie.setPath("/");
refreshTokenCookie.setHttpOnly(true);
refreshTokenCookie.setMaxAge(0); // 쿠키 만료 처리 (브라우저에서 삭제됨)
response.addCookie(refreshTokenCookie);

// Redis에서 refreshToken 삭제
if (refreshToken != null && !refreshToken.isEmpty()) {
redisService.deleteToken(refreshToken); // Redis에서 refreshToken 삭제
}


log.info("로그아웃 성공");
return ResponseEntity.ok().body("로그아웃 성공");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package intbyte4.learnsmate.admin.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class RedisService {

private final RedisTemplate<String, String> redisTemplate;

@Autowired
public RedisService(RedisTemplate<String, String> redisTemplate) {
this.redisTemplate = redisTemplate;
}

public void deleteToken(String refreshToken) {
if (refreshToken != null && !refreshToken.isEmpty()) {
redisTemplate.delete("refreshToken:" + refreshToken); // Redis에서 삭제
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR
throw new IllegalArgumentException("Authentication 객체가 CustomUserDetails 타입이 아닙니다.");
}

// CustomUserDetails로 캐스팅하여 사용자 정보를 가져옴
CustomUserDetails userDetails = (CustomUserDetails) authResult.getPrincipal();

// 사용자 정보 가져오기
Expand All @@ -100,18 +101,19 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR

// JWT 생성: JwtTokenDTO에 사용자 정보를 담고, roles와 함께 JWT 토큰을 생성
JwtTokenDTO tokenDTO = new JwtTokenDTO(userCode, userEmail, userName);
String accessToken = jwtUtil.generateToken(tokenDTO, roles, null); // JWT 생성 (roles와 추가적인 데이터를 페이로드에 담음)
String token = jwtUtil.generateToken(tokenDTO, roles, null); // JWT 생성 (roles와 추가적인 데이터를 페이로드에 담음)
String refreshToken = jwtUtil.generateRefreshToken(tokenDTO); // 7일

// 쿠키 생성
Cookie jwtCookie = new Cookie("accessToken", accessToken);
Cookie jwtCookie = new Cookie("token", token);
jwtCookie.setHttpOnly(true); // HTTP Only 속성으로 설정 (JavaScript에서 접근 불가)
jwtCookie.setSecure(false); // HTTPS 연결에서만 전송 (테스트 환경에서는 false 설정 가능)
// https://learnsmate.site -> 배포 환경시 true로 전환
jwtCookie.setPath("/"); // 쿠키의 유효 경로 설정 (애플리케이션 전체에 사용 가능)
jwtCookie.setMaxAge(4 * 3600); // 쿠키 만료 시간 설정 (4시간)
// 여기를 3-4시간정도로 만료시간 할건데 리프레시토큰을 해야하나? erp라 재로그인이 필요하지않을까

response.addCookie(jwtCookie);

// Refresh Token 쿠키 생성
Cookie refreshTokenCookie = new Cookie("refreshToken", refreshToken);
Expand All @@ -120,8 +122,6 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR
refreshTokenCookie.setPath("/"); // 유효 경로 설정
refreshTokenCookie.setMaxAge(7 * 24 * 3600); // Refresh Token의 만료 시간 (7일)

// 쿠키 응답에 추가
response.addCookie(jwtCookie);
response.addCookie(refreshTokenCookie);

saveRefreshTokenToRedis(userCode,refreshToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ public class JwtFilter extends OncePerRequestFilter {
private final AdminService userService;
private final JwtUtil jwtUtil; // JWT 토큰을 다루는 JwtUtil 클래스
private final List<String> excludeUrl // JWT 토큰 검증을 제외할 URL 패턴 목록
= Arrays.asList("/users/verification-email/**"
, "/users/nickname/check", "/users/verification-email/password", "/swagger-ui.html", "/swagger-ui/index.html"
, "/users/password");
= Arrays.asList("/admin/verification-email/**"
, "/admin/verification-email/password", "/swagger-ui.html", "/swagger-ui/index.html"
, "/admin/password");

public JwtFilter(AdminService userService, JwtUtil jwtUtil) {
this.userService = userService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ protected SecurityFilterChain configure(HttpSecurity http) throws Exception {
.requestMatchers(new AntPathRequestMatcher("/swagger-ui/**", "GET")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/v3/api-docs/**", "GET")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/admin/**","GET")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/auth/**","GET")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/auth/**","POST")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/admin/**","POST")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/users/**", "POST")).permitAll()
.requestMatchers(new AntPathRequestMatcher("/users/**", "OPTIONS")).permitAll()
Expand Down

0 comments on commit 71d5a86

Please sign in to comment.