Skip to content

Commit

Permalink
[FEAT] 모바일용 토큰 재발급 API (#192)
Browse files Browse the repository at this point in the history
* REFACTOR: 모바일 토큰 발급 API에 refresh 추가

* FEAT: 모바일 토큰 재발급 API
  • Loading branch information
oxdjww authored Dec 2, 2024
1 parent 3bef22e commit e20da51
Show file tree
Hide file tree
Showing 4 changed files with 229 additions and 154 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse
String path = request.getRequestURI();
if (path.startsWith("/health-check") || path.startsWith("/security-check")
|| path.startsWith("/auth/reissue") || path.startsWith("/login") || path.startsWith("/reissue")
|| path.matches("^/api/v2/mentors/\\d+$") || path.matches("^/api/v2/mentors/part$")) {
|| path.matches("^/api/v2/mentors/\\d+$") || path.matches("^/api/v2/mentors/part$") || path.matches("/oauth2/authorization/google")) {
System.out.println("jwt필터 통과로직");
filterChain.doFilter(request, response);
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,55 +1,63 @@
package com.soongsil.CoffeeChat.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.soongsil.CoffeeChat.config.jwt.JWTUtil;
import com.soongsil.CoffeeChat.controller.handler.ApiResponseGenerator;
import com.soongsil.CoffeeChat.service.CustomOAuth2UserService;
import com.soongsil.CoffeeChat.service.RefreshTokenService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController //RestController=Controller+ResponseBody
@RequestMapping("/auth")
@Tag(name = "REFRESHTOKEN", description = "리프레쉬 토큰 관련 api")
@RequiredArgsConstructor
public class RefreshTokenController { //Refresh토큰으로 Access토큰 발급 및 2차회원가입 컨트롤러
private final JWTUtil jwtUtil;
private final RefreshTokenService refreshTokenService;
private final JWTUtil jwtUtil;
private final RefreshTokenService refreshTokenService;

private final CustomOAuth2UserService oAuth2UserService;

private final CustomOAuth2UserService oAuth2UserService;
@PostMapping("/reissue")
@Operation(summary = "리프레쉬 토큰으로 액세스 토큰 reissue")
@ApiResponse(responseCode = "200", description = "헤더 : access, refresh, loginStatus")
public ResponseEntity<ApiResponseGenerator<String>> reissue(HttpServletRequest request,
HttpServletResponse response) {
//System.out.println("ㅇㅇ");
return ResponseEntity.ok().body(
ApiResponseGenerator.onSuccessOK(
refreshTokenService.reissueByRefreshToken(request, response)
)
);
}

@PostMapping("/reissue")
@Operation(summary = "리프레쉬 토큰으로 액세스 토큰 reissue")
@ApiResponse(responseCode = "200", description = "헤더 : access, refresh, loginStatus")
public ResponseEntity<ApiResponseGenerator<String>> reissue(HttpServletRequest request,
HttpServletResponse response) {
//System.out.println("ㅇㅇ");
return ResponseEntity.ok().body(
ApiResponseGenerator.onSuccessOK(
refreshTokenService.reissueByRefreshToken(request, response)
)
);
}
@PostMapping("/issue/mobile")
@Operation(summary = "[MOBILE] google 서버에서 받은 accessToken으로 서비스 accessToken 발급")
@ApiResponse(responseCode = "200", description = "유효한 google accessToken으로 요청시 body로 ROLE_USER 토큰 반환")
public ResponseEntity<ApiResponseGenerator<Map<String, String>>> issueAccessToken(@RequestParam String accessToken,
@RequestParam String name) {
return ResponseEntity.ok().body(
ApiResponseGenerator.onSuccessOK(
oAuth2UserService.verifyGoogleToken(accessToken, name)
)
);
}

@PostMapping("/reissue/mobile")
@Operation(summary = "리소스 서버에서 받은 accessToken으로 서비스 accessToken 발급")
@ApiResponse(responseCode = "200", description = "유효한 google accessToken으로 요청시 body로 ROLE_USER 토큰 반환")
public ResponseEntity<ApiResponseGenerator<String>> issueAccessToken(@RequestParam String accessToken,
@RequestParam String name) {
return ResponseEntity.ok().body(
ApiResponseGenerator.onSuccessOK(
oAuth2UserService.verifyGoogleToken(accessToken, name)
)
);
}
@PostMapping("/reissue/mobile")
@Operation(summary = "[MOBILE] refreshToken으로 서비스 accessToken, refreshToken 재발급")
@ApiResponse(responseCode = "200", description = "유효한 refreshToken 요청시 body로 accessToken, refreshToken 반환")
public ResponseEntity<ApiResponseGenerator<Map<String, String>>> reissueAccessTokenWithRefreshToken(
@RequestHeader String refreshToken) {
return ResponseEntity.ok().body(
ApiResponseGenerator.onSuccessOK(
refreshTokenService.reissueByRefreshTokenWithResponseBody(refreshToken)
));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

Expand All @@ -31,6 +32,7 @@ public class CustomOAuth2UserService extends DefaultOAuth2UserService {

private static final String GOOGLE_TOKEN_INFO_URL = "https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=";
private final UserService userService;
private final RefreshTokenService refreshTokenService;

private User findUserByUsername(String username) {
System.out.println("여기까지 들어옴");
Expand Down Expand Up @@ -96,7 +98,7 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic
}
}

public String verifyGoogleToken(String accessToken, String name) {
public Map<String,String> verifyGoogleToken(String accessToken, String name) {
log.info("[*] TOKEN>>>>> " + accessToken);
RestTemplate restTemplate = new RestTemplate();
String url = GOOGLE_TOKEN_INFO_URL + accessToken;
Expand All @@ -116,7 +118,18 @@ public String verifyGoogleToken(String accessToken, String name) {

log.info("[*] USER>>>>> EMAIL[" + mobileUserDTO.getEmail(), "] NAME[" + mobileUserDTO.getUsername() + "] ROLE[" + mobileUserDTO.getRole() + "]");

return jwtUtil.createJwt("access", mobileUserDTO.getUsername(), "ROLE_USER", 1800000000L);
String newAccessToken = jwtUtil.createJwt("access", mobileUserDTO.getUsername(), "ROLE_USER", 1800000000L); // Access token (30분)
String newRefreshToken = jwtUtil.createJwt("refresh", mobileUserDTO.getUsername(), "ROLE_USER", 86400000L); // Refresh token (24시간)

// Refresh 토큰을 Redis 또는 DB에 저장 (선택적)
refreshTokenService.addRefreshEntity(mobileUserDTO.getUsername(), newRefreshToken, 86400000L); // 24 hrs

// Access 및 Refresh 토큰 반환
Map<String, String> tokens = new HashMap<>();
tokens.put("accessToken", newAccessToken);
tokens.put("refreshToken", newRefreshToken);

return tokens;
} else {
log.error("===== Invalid token info ===== " + tokenInfo);
throw new CustomException(INVALID_TOKEN.getHttpStatusCode(), INVALID_TOKEN.getErrorMessage());
Expand All @@ -126,5 +139,4 @@ public String verifyGoogleToken(String accessToken, String name) {
throw new CustomException(INVALID_TOKEN.getHttpStatusCode(), e.getResponseBodyAsString());
}
}

}
Loading

0 comments on commit e20da51

Please sign in to comment.