diff --git a/server_config b/server_config index 864626a..8d77765 160000 --- a/server_config +++ b/server_config @@ -1 +1 @@ -Subproject commit 864626ab477ee0afdfa8172680c4594a531d9094 +Subproject commit 8d777656d7c206e48e3e60039679b064d4a8db1f diff --git a/src/main/java/com/chwipoClova/common/config/WebSecurityConfig.java b/src/main/java/com/chwipoClova/common/config/WebSecurityConfig.java index 2b70b70..3f62a6f 100644 --- a/src/main/java/com/chwipoClova/common/config/WebSecurityConfig.java +++ b/src/main/java/com/chwipoClova/common/config/WebSecurityConfig.java @@ -58,7 +58,7 @@ public SecurityFilterChain securityFilterChain(final @NotNull HttpSecurity http authorize //.requestMatchers("/**").permitAll().anyRequest().authenticated() .requestMatchers("/" - ,"/user/getKakaoUrl","/user/kakaoLogin","/user/kakaoCallback","/user/logout" + ,"/user/getKakaoUrl","/user/kakaoLogin", "/user/getKakaoDevUrl", "/user/kakaoDevLogin", "/user/kakaoCallback","/user/logout" ).permitAll().anyRequest().authenticated() //.requestMatchers(HttpMethod.OPTIONS, "/**").permitAll() diff --git a/src/main/java/com/chwipoClova/user/controller/UserController.java b/src/main/java/com/chwipoClova/user/controller/UserController.java index 1416a80..a6a687b 100644 --- a/src/main/java/com/chwipoClova/user/controller/UserController.java +++ b/src/main/java/com/chwipoClova/user/controller/UserController.java @@ -55,6 +55,16 @@ public UserSnsUrlRes getKakaoUrl() throws Exception { return userService.getKakaoUrl(); } + @Operation(summary = "카카오 개발 로그인 URL", description = "카카오 개발 로그인 URL") + @GetMapping("/getKakaoDevUrl") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "OK") + } + ) + public UserSnsUrlRes getKakaoDevUrl() throws Exception { + return userService.getKakaoLocalUrl(); + } + @Operation(summary = "카카오 로그인", description = "카카오 로그인 (카카오 로그인 URL 호출해서 로그인 성공하면 나오는 코드를 입력)") @GetMapping("/kakaoLogin") @ApiResponses(value = { @@ -66,6 +76,18 @@ public CommonResponse kakaoLogin(@Schema(description = "로그인코드", exampl return userService.kakaoLogin(code, response); } + @Operation(summary = "카카오 개발 로그인", description = "카카오 개발 로그인 (카카오 로그인 URL 호출해서 로그인 성공하면 나오는 코드를 입력)") + @GetMapping("/kakaoDevLogin") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = UserLoginRes.class))), + @ApiResponse(responseCode = "700", description = "신규 가입되었습니다.", content = @Content(schema = @Schema(implementation = String.class))) + } + ) + public CommonResponse kakaoDevLogin(@Schema(description = "로그인코드", example = "1", name = "code") @RequestParam(name = "code") String code, HttpServletResponse response) throws Exception { + return userService.kakaoDevLogin(code, response); + } + + @Hidden @Operation(summary = "카카오 로그인 콜백", description = "카카오 로그인 콜백") @GetMapping("/kakaoCallback") diff --git a/src/main/java/com/chwipoClova/user/service/UserService.java b/src/main/java/com/chwipoClova/user/service/UserService.java index f7f7f16..14d46cd 100644 --- a/src/main/java/com/chwipoClova/user/service/UserService.java +++ b/src/main/java/com/chwipoClova/user/service/UserService.java @@ -68,6 +68,9 @@ public class UserService { @Value("${kakao.redirect_uri}") private String redirectUri; + @Value("${kakao.redirect_local_uri}") + private String redirectLocalUri; + public UserSnsUrlRes getKakaoUrl() { String kakaoUrl = kakaoAuthUrl + "?response_type=code" + "&client_id=" + clientId @@ -229,4 +232,99 @@ public UserInfoRes selectUserInfoForUserId(Long userId) { .modifyDate(user.getModifyDate()) .build(); } + + public UserSnsUrlRes getKakaoLocalUrl() { + String kakaoUrl = kakaoAuthUrl + "?response_type=code" + "&client_id=" + clientId + + "&redirect_uri=" + redirectLocalUri; + UserSnsUrlRes userSnsUrlRes = UserSnsUrlRes.builder() + .url(kakaoUrl) + .build(); + return userSnsUrlRes; + } + + public CommonResponse kakaoDevLogin(String code, HttpServletResponse response) { + KakaoToken kakaoToken = requestDevAccessToken(code); + KakaoUserInfo kakaoUserInfo = requestOauthInfo(kakaoToken); + + long snsId = kakaoUserInfo.getId(); + String email = kakaoUserInfo.getEmail(); + String nickname = kakaoUserInfo.getNickname(); + Integer snsType = kakaoUserInfo.getOAuthProvider().getCode(); + String thumbnailImageUrl = kakaoUserInfo.getThumbnailImageUrl(); + String profileImageUrl = kakaoUserInfo.getProfileImageUrl(); + + Optional userInfo = userRepository.findBySnsTypeAndSnsId(snsType, snsId); + + // 유저 정보가 있다면 업데이트 없으면 등록 + if (userInfo.isPresent()) { + User userInfoRst = userInfo.get(); + + Long userId = userInfoRst.getUserId(); + + TokenDto tokenDto = jwtUtil.createAllToken(String.valueOf(userId)); + + // Refresh토큰 있는지 확인 + Optional refreshToken = tokenRepository.findByUserUserId(userInfoRst.getUserId()); + + // 있다면 새토큰 발급후 업데이트 + // 없다면 새로 만들고 디비 저장 + if(refreshToken.isPresent()) { + tokenRepository.save(refreshToken.get().updateToken(tokenDto.getRefreshToken())); + }else { + Token newToken = new Token(tokenDto.getRefreshToken(), User.builder().userId(userInfoRst.getUserId()).build()); + tokenRepository.save(newToken); + } + + // response 헤더에 Access Token / Refresh Token 넣음 + jwtUtil.setResonseJwtToken(response, tokenDto.getAccessToken(), tokenDto.getRefreshToken()); + + UserLoginRes userLoginRes = UserLoginRes.builder() + .snsId(userInfoRst.getSnsId()) + .userId(userId) + .email(userInfoRst.getEmail()) + .name(userInfoRst.getName()) + .snsType(userInfoRst.getSnsType()) + .thumbnailImage(userInfoRst.getThumbnailImage()) + .profileImage(userInfoRst.getProfileImage()) + .regDate(userInfoRst.getRegDate()) + .modifyDate(userInfoRst.getModifyDate()) + .build(); + + return new CommonResponse<>(String.valueOf(HttpStatus.OK.value()), userLoginRes, HttpStatus.OK.getReasonPhrase()); + } else { + log.info("신규유저 등록 {}", nickname); + User user = User.builder() + .snsId(snsId) + .email(email) + .name(nickname) + .snsType(snsType) + .thumbnailImage(thumbnailImageUrl) + .profileImage(profileImageUrl) + .regDate(new Date()) + .build(); + userRepository.save(user); + return new CommonResponse<>(MessageCode.NEW_USER.getCode(), null, MessageCode.NEW_USER.getMessage()); + } + } + + private KakaoToken requestDevAccessToken(String code) { + + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + MultiValueMap body = new LinkedMultiValueMap<>();; + body.add("grant_type", grantType); + body.add("client_id", clientId); + body.add("client_secret", clientSecret); + body.add("redirect_uri", redirectLocalUri); + body.add("code", code); + + HttpEntity> request = new HttpEntity<>(body, httpHeaders); + + KakaoToken response = restTemplate.postForObject(tokenUrl, request, KakaoToken.class); + + // TODO 토큰 정보를 가져오지 못하면 예외발생 처리 추가 + assert response != null; + return response; + } }