- [Springboot] 41. OAuth 2.0 (3단계-Kakao Developers 소셜 로그인 API 토큰 받기)2024년 08월 16일
- Song hyun
- 작성자
- 2024.08.16.:48
728x90반응형[Springboot] 41. OAuth 2.0 (3단계-Kakao Developers 소셜 로그인 API 토큰 받기)
1. 문서 살펴보기
https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api
2. 토큰 받아오기
@GetMapping("/kakao") @ResponseBody // @RestController = @Controller + @ResponseBody public String getMethodName(@RequestParam(name="code") String code) { System.out.println("code : "+code); // POST - 카카오 토큰 요청 받기 // header, body 구성 RestTemplate rt1 = new RestTemplate(); // 헤더 구성 HttpHeaders header1 = new HttpHeaders(); header1.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8"); // 바디 구성 MultiValueMap<String, String> params1 = new LinkedMultiValueMap<String,String>(); params1.add("grant_type", "authorization_code"); params1.add("client_id", "e6c387d854fa01be9131e377baa4686f"); params1.add("redirect_uri", "http://localhost:8080/user/kakao"); params1.add("code", code); // 헤더+바디 결합 HttpEntity<MultiValueMap<String,String>> reqKakaoMessage = new HttpEntity<>(params1,header1); // 통신 요청 ResponseEntity<String> response= rt1.exchange("https://kauth.kakao.com/oauth/token", HttpMethod.POST, reqKakaoMessage, String.class); System.out.println("response : "+response); return response.getBody().toString(); }
3. jsonschema2pojo 사용하기
https://www.jsonschema2pojo.org/
package com.tenco.bank.dto; import java.util.LinkedHashMap; import java.util.Map; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyOrder; @JsonInclude(JsonInclude.Include.NON_NULL) @JsonPropertyOrder({ "access_token", "token_type", "refresh_token", "expires_in", "scope", "refresh_token_expires_in" }) public class OAuthToken { @JsonProperty("access_token") private String accessToken; @JsonProperty("token_type") private String tokenType; @JsonProperty("refresh_token") private String refreshToken; @JsonProperty("expires_in") private Integer expiresIn; @JsonProperty("scope") private String scope; @JsonProperty("refresh_token_expires_in") private Integer refreshTokenExpiresIn; @JsonIgnore private Map<String, Object> additionalProperties = new LinkedHashMap<String, Object>(); @JsonProperty("access_token") public String getAccessToken() { return accessToken; } @JsonProperty("access_token") public void setAccessToken(String accessToken) { this.accessToken = accessToken; } @JsonProperty("token_type") public String getTokenType() { return tokenType; } @JsonProperty("token_type") public void setTokenType(String tokenType) { this.tokenType = tokenType; } @JsonProperty("refresh_token") public String getRefreshToken() { return refreshToken; } @JsonProperty("refresh_token") public void setRefreshToken(String refreshToken) { this.refreshToken = refreshToken; } @JsonProperty("expires_in") public Integer getExpiresIn() { return expiresIn; } @JsonProperty("expires_in") public void setExpiresIn(Integer expiresIn) { this.expiresIn = expiresIn; } @JsonProperty("scope") public String getScope() { return scope; } @JsonProperty("scope") public void setScope(String scope) { this.scope = scope; } @JsonProperty("refresh_token_expires_in") public Integer getRefreshTokenExpiresIn() { return refreshTokenExpiresIn; } @JsonProperty("refresh_token_expires_in") public void setRefreshTokenExpiresIn(Integer refreshTokenExpiresIn) { this.refreshTokenExpiresIn = refreshTokenExpiresIn; } @JsonAnyGetter public Map<String, Object> getAdditionalProperties() { return this.additionalProperties; } @JsonAnySetter public void setAdditionalProperty(String name, Object value) { this.additionalProperties.put(name, value); } }
4. OAuthToken (Oauth DTO 만들기)
*@JsonNaming
package com.tenco.bank.dto; import com.fasterxml.jackson.databind.PropertyNamingStrategies; import com.fasterxml.jackson.databind.annotation.JsonNaming; import lombok.Data; import lombok.ToString; // JSON 형식에 // 코딩 컨벤션을 스네이크 케이스에서 카멜 노테이션으로 할당하라 @Data @ToString @JsonNaming(value = PropertyNamingStrategies.SnakeCaseStrategy.class) public class OAuthToken { private String accessToken; private String tokenType; private String refreshToken; private Integer expiresIn; private String scope; private Integer refreshTokenExpiresIn; }
package com.tenco.bank.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; 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.ResponseBody; import org.springframework.web.client.RestTemplate; import org.springframework.web.util.UriComponentsBuilder; import com.tenco.bank.utils.Define; import com.tenco.bank.dto.OAuthToken; import com.tenco.bank.dto.SignInDTO; import com.tenco.bank.dto.SignUpDTO; import com.tenco.bank.handler.exception.DataDeliveryException; import com.tenco.bank.repository.model.User; import com.tenco.bank.service.UserService; import jakarta.servlet.http.HttpSession; @Controller // IoC에 대상(싱글톤 패턴으로 관리됨) @RequestMapping("/user") // 대문 처리 public class UserController { private UserService userService; private final HttpSession session; // DI 처리 @Autowired // 노란색 경고는 사용할 필요 없음 - 가독성 위해서 선언해도 됨 public UserController(UserService service, HttpSession session) { this.userService = service; this.session = session; } /** * 회원 가입 페이지 요청 * 주소 설계 : http://localhost:8080/user/sign-up * @return signUp.jsp */ @GetMapping("/sign-up") public String signUpPage() { // prefix: /WEB-INF/view/ // return: user/signUp // suffix: .jsp return "user/signUp"; } /** * 회원 가입 로직 처리 요청 * 주소 설계 : http://localhost:8080/user/sign-up * @param dto * @return */ @PostMapping("/sign-up") public String signUpProc(SignUpDTO dto) { // controller 에서 일반적이 코드 작업 // 1. 인증검사 (여기서는 인증검사 불 필요) // 2. 유효성 검사 if(dto.getUsername() == null || dto.getUsername().isEmpty()) { throw new DataDeliveryException(Define.ENTER_YOUR_USERNAME, HttpStatus.BAD_REQUEST); } if(dto.getPassword() == null || dto.getPassword().isEmpty()) { throw new DataDeliveryException(Define.ENTER_YOUR_PASSWORD, HttpStatus.BAD_REQUEST); } if(dto.getFullname() == null || dto.getFullname().isEmpty()) { throw new DataDeliveryException(Define.ENTER_YOUR_FULLNAME, HttpStatus.BAD_REQUEST); } userService.createUser(dto); return "redirect:/user/sign-in"; } /* * 로그인 화면 요청 * 주소설계 : http://localhost:8080/user/sign-in */ @GetMapping("/sign-in") public String singInPage() { // 인증검사 x // 유효성검사 x return "user/signIn"; } /** * 로그인 요청 처리 * 주소설계 : http://localhost:8080/user/sign-in * @return */ @PostMapping("/sign-in") public String signProc(SignInDTO dto) { // 1. 인증 검사 x // 2. 유효성 검사 if(dto.getUsername() == null || dto.getUsername().isEmpty()) { throw new DataDeliveryException(Define.ENTER_YOUR_USERNAME, HttpStatus.BAD_REQUEST); } if(dto.getPassword() == null || dto.getPassword().isEmpty()) { throw new DataDeliveryException(Define.ENTER_YOUR_PASSWORD, HttpStatus.BAD_REQUEST); } // 서비스 호출 User principal = userService.readUser(dto); // 세션 메모리에 등록 처리 session.setAttribute(Define.PRINCIPAL, principal); // 새로운 페이지로 이동 처리 // TODO - 계좌 목록 페이지 이동처리 예정 return "redirect:/index"; } // 코드 추가 @GetMapping("/logout") public String logout() { session.invalidate(); // 로그아웃 됨 return "redirect:/user/sign-in"; } @GetMapping("/kakao") @ResponseBody // @RestController = @Controller + @ResponseBody public String getMethodName(@RequestParam(name="code") String code) { System.out.println("code : "+code); // POST - 카카오 토큰 요청 받기 // header, body 구성 RestTemplate rt1 = new RestTemplate(); // 헤더 구성 HttpHeaders header1 = new HttpHeaders(); header1.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8"); // 바디 구성 MultiValueMap<String, String> params1 = new LinkedMultiValueMap<String,String>(); params1.add("grant_type", "authorization_code"); params1.add("client_id", "e6c387d854fa01be9131e377baa4686f"); params1.add("redirect_uri", "http://localhost:8080/user/kakao"); params1.add("code", code); // 헤더+바디 결합 HttpEntity<MultiValueMap<String,String>> reqKakaoMessage = new HttpEntity<>(params1,header1); // 통신 요청 ResponseEntity<OAuthToken> response= rt1.exchange("https://kauth.kakao.com/oauth/token", HttpMethod.POST, reqKakaoMessage, OAuthToken.class); System.out.println("response : "+response.getBody().toString()); return response.getBody().toString(); } }
728x90반응형'Springboot' 카테고리의 다른 글
[Springboot] 43. OAuth 2.0 (5단계-소셜 로그인 API 연동- 자동 회원가입/로그인 처리) (1) 2024.08.16 [Springboot] 42. OAuth 2.0 (4단계-Kakao Developers 소셜 로그인 사용자 정보 받아오기) (0) 2024.08.16 [Springboot] 40. OAuth 2.0 (2단계-Kakao Developers API 응답 코드 받기) (0) 2024.08.14 [Springboot] 39. OAuth 2.0 (1단계-Kakao Developers 사용하기) (0) 2024.08.14 [Springboot] 38. Server to Server란? (0) 2024.08.14 다음글이전글이전 글이 없습니다.댓글
스킨 업데이트 안내
현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)