////
Search
Duplicate

oauth

OAuth 정의

OAuth는 인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 개방형 표준이다.
Plain Text
복사
REST API를 이용하는 카카오 로그인 과정

KakaoController.java

프론트를 고려하지 않은 코드
@Controller @RequiredArgsConstructor public class KakaoController { private final KakaoService kakaoService; @GetMapping("/kakao-login") public String homepage() { return "kakao"; } @GetMapping("${kakao.redirect-uri}") public String kakaoLogin(@RequestParam String code, HttpServletResponse response) throws JsonProcessingException { kakaoService.kakaoLogin(code, response); return "redirect:/kakao-login"; } }
JavaScript
복사
문제점이 무엇일까요?
프론트를 고려한 코드
@Controller @RequiredArgsConstructor public class KakaoController { private final KakaoService kakaoService; @ResponseBody @GetMapping("/api/${mpt.version}/users/kakao-code") public RedirectView redirectView() { String url = kakaoService.redirect(); return new RedirectView(url); } @GetMapping("/api/${mpt.version}/users/kakao-login") public void kakaoLogin(@RequestParam String code, HttpServletResponse response) throws JsonProcessingException { kakaoService.kakaoLogin(code, response); } }
JavaScript
복사

KakaoService.java

1.
인가 코드 받기
a.
public String redirect() { return "https://kauth.kakao.com/oauth/authorize?response_type=code&client_id=" + CLIENT_ID + "&redirect_uri=" + TARGET_IP + REDIRECT_URI; }
JavaScript
복사
2.
토큰 받기
a.
private String getToken(String code) throws JsonProcessingException { String TOKEN_URI = "https://kauth.kakao.com/oauth/token"; String GRANT_TYPE = "?grant_type=authorization_code"; RestClient restClient = RestClient.create(); String response = restClient .post() .uri( TOKEN_URI + GRANT_TYPE + "&client_id=" + CLIENT_ID + "&redirect_uri=" + TARGET_IP + REDIRECT_URI + "&code=" + code + "&client_secret=" + SECRET_KEY) .header("Content-type", "application/x-www-form-urlencoded;charset=utf-8") .retrieve() .body(String.class); JsonNode jsonNode = new ObjectMapper().readTree(response); return jsonNode.get("access_token").asText(); }
JavaScript
복사
3.
사용자 정보 가져오기
a.
private UserSignUpReq getKaKaoUserInfo(String accessToken) throws JsonProcessingException { String INFO_URI = "https://kapi.kakao.com/v2/user/me"; RestClient restClient = RestClient.create(); String response = restClient .get() .uri(INFO_URI) .header("Authorization", "Bearer " + accessToken) .header("Content-type", "application/x-www-form-urlencoded;charset=utf-8") .retrieve() .body(String.class); JsonNode jsonNode = new ObjectMapper().readTree(response); String nickname = jsonNode.get("properties").get("nickname").asText(); String email = jsonNode.get("kakao_account").get("email").asText(); return UserSignUpReq.builder() .email(email) .password(UUID.randomUUID().toString()) .username(nickname) .build(); }
JavaScript
복사
4.
응답 헤더에 jwt 토큰 보내기
a.
public void kakaoLogin(String code, HttpServletResponse response) throws JsonProcessingException { String accessToken = getToken(code); UserSignUpReq req = getKaKaoUserInfo(accessToken); UserEntity userEntity = UserEntity.builder() .email(req.email()) .username(req.username()) .password(req.password()) .build(); if (userRepository.findByEmail(req.email()).isEmpty()) { userRepository.save(userEntity); } String token = jwtUtil.createToken(userEntity.getEmail()); log.info(token); response.addHeader(TOKEN_HEADER, token); }
JavaScript
복사