-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FEAT] 카카오 auth
- Loading branch information
Showing
38 changed files
with
1,519 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
126 changes: 126 additions & 0 deletions
126
src/main/java/com/haemil/backend/auth/controller/AuthController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
package com.haemil.backend.auth.controller; | ||
|
||
import com.haemil.backend.auth.dto.LoginDto; | ||
import com.haemil.backend.auth.dto.RespLoginDto; | ||
import com.haemil.backend.auth.dto.SuccessDto; | ||
import com.haemil.backend.auth.dto.kakao.KakaoLoginParams; | ||
import com.haemil.backend.auth.service.AuthService; | ||
import com.haemil.backend.global.config.BaseException; | ||
import com.haemil.backend.global.config.BaseResponse; | ||
import com.haemil.backend.global.security.jwt.AuthTokens; | ||
import com.haemil.backend.user.entity.UserRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.HttpStatus; | ||
import org.springframework.http.ResponseCookie; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
@Slf4j | ||
@RestController | ||
@RequiredArgsConstructor | ||
@RequestMapping("/auth") | ||
public class AuthController { | ||
|
||
private final AuthService authService; | ||
private final UserRepository userRepository; | ||
|
||
@Value("${jwt.cookie-period}") | ||
private long CookiePeriod; | ||
|
||
@PostMapping("/kakao") | ||
public ResponseEntity<BaseResponse> loginKakao(@RequestParam Boolean isGuardian, @RequestBody KakaoLoginParams params) { | ||
try { | ||
log.debug("isGuardian = {}", isGuardian); | ||
RespLoginDto respLoginDto = authService.login(params, isGuardian); | ||
|
||
HttpHeaders headers = respLoginDto.getHeaders(); | ||
LoginDto loginDto = respLoginDto.getLoginDto(); | ||
|
||
return ResponseEntity.ok().headers(headers).body(new BaseResponse<>(loginDto)); | ||
} catch (BaseException e){ | ||
return new BaseResponse<>(e.getStatus()).convert(); | ||
} | ||
} | ||
|
||
// 토큰 재발급 | ||
@PostMapping("/reissue") | ||
public ResponseEntity<?> reissue(@CookieValue(name = "refresh-token") String requestRefreshToken, | ||
@RequestHeader("Authorization") String requestAccessToken) { | ||
|
||
AuthTokens.TokenDto reissuedTokenDto = authService.reissue(requestAccessToken, requestRefreshToken); | ||
|
||
SuccessDto successDto; | ||
if (reissuedTokenDto != null) { // 토큰 재발급 성공 | ||
// RT 저장 | ||
ResponseCookie responseCookie = ResponseCookie.from("refresh-token", reissuedTokenDto.getRefreshToken()) | ||
.maxAge(CookiePeriod) | ||
// .domain(".photohere.co.kr") | ||
.path("/") | ||
.sameSite("None") | ||
.httpOnly(true) | ||
.secure(true) | ||
.build(); | ||
// success true | ||
successDto = SuccessDto.builder().success(true).build(); | ||
return ResponseEntity | ||
.status(HttpStatus.OK) | ||
.header(HttpHeaders.SET_COOKIE, responseCookie.toString()) | ||
// AT 저장 | ||
.header(HttpHeaders.AUTHORIZATION, "Bearer " + reissuedTokenDto.getAccessToken()) | ||
.body(successDto); | ||
// .build(); | ||
|
||
} else { // Refresh Token 탈취 가능성 | ||
// Cookie 삭제 후 재로그인 유도 | ||
ResponseCookie responseCookie = ResponseCookie.from("refresh-token", "") | ||
.maxAge(0) | ||
.path("/") | ||
.build(); | ||
// success false | ||
successDto = SuccessDto.builder().success(false).build(); | ||
|
||
return ResponseEntity | ||
.status(HttpStatus.UNAUTHORIZED) | ||
.header(HttpHeaders.SET_COOKIE, responseCookie.toString()) | ||
.body(successDto); | ||
// .build(); | ||
} | ||
} | ||
|
||
// temp mapping - find cookie | ||
|
||
@RequestMapping("/getCookie1") | ||
public ResponseEntity<BaseResponse<String>> getCookie1(@CookieValue String useremail, @CookieValue("useremail") String umail) { | ||
System.out.println(umail); | ||
return ResponseEntity.ok().body(new BaseResponse<>("test.")); | ||
} | ||
|
||
// -- | ||
|
||
// 로그아웃 | ||
@PostMapping("/logout") | ||
public ResponseEntity<?> logout(@RequestHeader("Authorization") String requestAccessToken) { | ||
try { | ||
// RT가 null이 아니면서 empty가 아닌 경우 로그아웃 진행. | ||
if (requestAccessToken != null && !requestAccessToken.isEmpty()) | ||
authService.logout(requestAccessToken); | ||
ResponseCookie responseCookie = ResponseCookie.from("refresh-token", "") | ||
.maxAge(0) | ||
.path("/") | ||
.build(); | ||
|
||
HttpHeaders headers = new HttpHeaders(); | ||
headers.add(HttpHeaders.SET_COOKIE, responseCookie.toString()); | ||
|
||
return ResponseEntity.ok().headers(headers).body(new BaseResponse<>("로그아웃 되었습니다.")); | ||
} catch (BaseException e){ | ||
return new BaseResponse<>(e.getStatus()).convert(); | ||
} | ||
|
||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.haemil.backend.auth.dto; | ||
|
||
import lombok.Builder; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@Builder | ||
public class LoginDto { | ||
|
||
private String nickname; | ||
private String profileImageUrl; | ||
private Long userId; | ||
// 추가: AT | ||
private String accessToken; | ||
|
||
public LoginDto(String nickname, String profileImageUrl, Long userId, String accessToken) { | ||
this.nickname = nickname; | ||
this.profileImageUrl = profileImageUrl; | ||
this.userId = userId; | ||
this.accessToken = accessToken; | ||
} | ||
} | ||
|
21 changes: 21 additions & 0 deletions
21
src/main/java/com/haemil/backend/auth/dto/RespLoginDto.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.haemil.backend.auth.dto; | ||
|
||
import org.springframework.http.HttpHeaders; | ||
|
||
public class RespLoginDto { | ||
private HttpHeaders headers; | ||
private LoginDto loginDto; | ||
|
||
public RespLoginDto(HttpHeaders headers, LoginDto loginDto) { | ||
this.headers = headers; | ||
this.loginDto = loginDto; | ||
} | ||
|
||
public HttpHeaders getHeaders() { | ||
return headers; | ||
} | ||
|
||
public LoginDto getLoginDto() { | ||
return loginDto; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.haemil.backend.auth.dto; | ||
|
||
import lombok.Builder; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@Builder | ||
public class SuccessDto { | ||
private Boolean success; | ||
} |
80 changes: 80 additions & 0 deletions
80
src/main/java/com/haemil/backend/auth/dto/kakao/KakaoApiClient.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package com.haemil.backend.auth.dto.kakao; | ||
|
||
import com.haemil.backend.global.security.oauth.OAuthApiClient; | ||
import com.haemil.backend.global.security.oauth.OAuthInfoResponse; | ||
import com.haemil.backend.global.security.oauth.OAuthLoginParams; | ||
import com.haemil.backend.global.security.oauth.OAuthProvider; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.http.HttpEntity; | ||
import org.springframework.http.HttpHeaders; | ||
import org.springframework.http.MediaType; | ||
import org.springframework.stereotype.Component; | ||
import org.springframework.util.LinkedMultiValueMap; | ||
import org.springframework.util.MultiValueMap; | ||
import org.springframework.web.client.RestTemplate; | ||
|
||
@Component | ||
@RequiredArgsConstructor | ||
@Slf4j | ||
public class KakaoApiClient implements OAuthApiClient { | ||
|
||
private static final String GRANT_TYPE = "authorization_code"; | ||
|
||
@Value("${oauth.kakao.url.auth}") | ||
private String authUrl; | ||
|
||
@Value("${oauth.kakao.url.api}") | ||
private String apiUrl; | ||
|
||
@Value("${oauth.kakao.client-id}") | ||
private String clientId; | ||
|
||
@Value("${oauth.kakao.client-secret}") | ||
private String clientSecret; | ||
|
||
private final RestTemplate restTemplate; | ||
// restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory()); | ||
|
||
|
||
@Override | ||
public OAuthProvider oAuthProvider() { | ||
return OAuthProvider.KAKAO; | ||
} | ||
|
||
@Override | ||
public String requestAccessToken(OAuthLoginParams params) { | ||
String url = authUrl + "/oauth/token"; | ||
|
||
HttpHeaders httpHeaders = new HttpHeaders(); | ||
httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED); | ||
|
||
MultiValueMap<String, String> body = params.makeBody(); | ||
body.add("grant_type", GRANT_TYPE); | ||
body.add("client_id", clientId); | ||
|
||
HttpEntity<?> request = new HttpEntity<>(body, httpHeaders); | ||
|
||
KakaoTokens response = restTemplate.postForObject(url, request, KakaoTokens.class); | ||
|
||
assert response != null; | ||
return response.getAccessToken(); | ||
} | ||
|
||
@Override | ||
public OAuthInfoResponse requestOauthInfo(String accessToken) { | ||
String url = apiUrl + "/v2/user/me"; | ||
|
||
HttpHeaders httpHeaders = new HttpHeaders(); | ||
httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED); | ||
httpHeaders.set("Authorization", "Bearer " + accessToken); | ||
|
||
MultiValueMap<String, String> body = new LinkedMultiValueMap<>(); | ||
body.add("property_keys", "[\"kakao_account.email\", \"kakao_account.profile\"]"); | ||
log.info("call request user/me"); | ||
HttpEntity<?> request = new HttpEntity<>(body, httpHeaders); | ||
|
||
return restTemplate.postForObject(url, request, KakaoInfoResponse.class); | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
src/main/java/com/haemil/backend/auth/dto/kakao/KakaoInfoResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package com.haemil.backend.auth.dto.kakao; | ||
|
||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||
import com.fasterxml.jackson.annotation.JsonProperty; | ||
import com.haemil.backend.global.security.oauth.OAuthInfoResponse; | ||
import com.haemil.backend.global.security.oauth.OAuthProvider; | ||
import lombok.Getter; | ||
|
||
@Getter | ||
@JsonIgnoreProperties(ignoreUnknown = true) | ||
public class KakaoInfoResponse implements OAuthInfoResponse { | ||
|
||
@JsonProperty("kakao_account") | ||
private KakaoAccount kakaoAccount; | ||
|
||
@Getter | ||
@JsonIgnoreProperties(ignoreUnknown = true) | ||
static class KakaoAccount { | ||
private KakaoProfile profile; | ||
private String email; | ||
} | ||
|
||
@Getter | ||
@JsonIgnoreProperties(ignoreUnknown = true) | ||
static class KakaoProfile { | ||
private String nickname; | ||
private String profileImageUrl; | ||
} | ||
|
||
@Override | ||
public String getEmail() { | ||
return kakaoAccount.email; | ||
} | ||
|
||
@Override | ||
public String getNickname() { | ||
return kakaoAccount.profile.nickname; | ||
} | ||
|
||
@Override | ||
public String getProfileImageUrl() { | ||
return kakaoAccount.profile.profileImageUrl; | ||
} | ||
|
||
@Override | ||
public OAuthProvider getOAuthProvider() { | ||
return OAuthProvider.KAKAO; | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
src/main/java/com/haemil/backend/auth/dto/kakao/KakaoLoginParams.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.haemil.backend.auth.dto.kakao; | ||
|
||
import com.haemil.backend.global.security.oauth.OAuthLoginParams; | ||
import com.haemil.backend.global.security.oauth.OAuthProvider; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.util.LinkedMultiValueMap; | ||
import org.springframework.util.MultiValueMap; | ||
|
||
@Slf4j | ||
@Getter | ||
@NoArgsConstructor | ||
public class KakaoLoginParams implements OAuthLoginParams { | ||
private String authorizationCode; | ||
|
||
@Override | ||
public OAuthProvider oAuthProvider() { | ||
return OAuthProvider.KAKAO; | ||
} | ||
|
||
@Override | ||
public MultiValueMap<String, String> makeBody() { | ||
MultiValueMap<String, String> body = new LinkedMultiValueMap<>(); | ||
body.add("code", authorizationCode); | ||
return body; | ||
} | ||
} |
Oops, something went wrong.