[내일배움캠프] #211115 💻 TIL 💻

이수영·2021년 11월 15일
0

MY TIL 

목록 보기
36/50

📚 Springboot

✍🏻 소셜로그인

📌 OAuth

  • 인터넷 사용자들이 비밀번호를 제공하지 않고도 다른 웹사이트 상(네이버로그인,카카오로그인)의 자신들의 정보에 대해 웹사이트나 애플리케이션에게 접근권한을 부여할 수 있는 공통적인 수단으로서 사용되는 , 접근위임을 위한 개방형 표준
  • 사용자가 애플리케이션에게 모든 권한을 넘기지 않고 사용자 대신 서비스를 이용할 수 있게 해주는 http기반의 보안 프로토콜
  • ex . 서비스제공자 : 네이버 카카오 구글 페이스북 등등

📌 카카오 로그인

  • 내가 애플리케이션 등록을 통해 받은 REST KEY로 인증코드 요청 -> 전달받음

  • 사용자가 카카오로그인페이지를 통해 '동의하고 계속하기' 누르면 미리 설정해둔 (카카오 디벨로퍼) Redirect URI (callback)로 인가토큰이 전달된다

  • usercontroller 에서 Redirect URI (callback)를 통해 인가토큰 받고 userService 호출 => userService의 kakaologin 메소드에서 kakaoOAuth를 호출해서 애플리케이션이 사용자의 정보에 접근하도록 허용한다 => 카카오로그인 후 회원정보가 userRepository에 저장

  • ✔ KakaoOAuth2

package com.sparta.springcore.security.kakao;

import org.json.JSONObject;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

@Component
public class KakaoOAuth2 {
    public KakaoUserInfo getUserInfo(String authorizedCode) {
        // 1. 인가코드 -> 액세스 토큰
        // authorizedCode: 카카오 서버로부터 받은 인가 코드
        String accessToken = getAccessToken(authorizedCode);
        // 2. 액세스 토큰 -> 카카오 사용자 정보에 접근 
        KakaoUserInfo userInfo = getUserInfoByToken(accessToken);

        return userInfo;
    }

    private String getAccessToken(String authorizedCode) {
        // HttpHeader 오브젝트 생성
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

        // HttpBody 오브젝트 생성
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        params.add("grant_type", "authorization_code");
        params.add("client_id", "*{본인의 REST API키}*");
        params.add("redirect_uri", "http://localhost:8080/user/kakao/callback");
        params.add("code", authorizedCode);

        // HttpHeader와 HttpBody를 하나의 오브젝트에 담기
        RestTemplate rt = new RestTemplate();
        HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest =
                new HttpEntity<>(params, headers);

        // Http 요청하기 - Post방식으로 - 그리고 response 변수의 응답 받음.
        ResponseEntity<String> response = rt.exchange(
                "https://kauth.kakao.com/oauth/token",
                HttpMethod.POST,
                kakaoTokenRequest,
                String.class
        );

        // JSON -> 액세스 토큰 파싱
        String tokenJson = response.getBody();
        JSONObject rjson = new JSONObject(tokenJson);
        String accessToken = rjson.getString("access_token");

        return accessToken;
    }

    private KakaoUserInfo getUserInfoByToken(String accessToken) {
        // HttpHeader 오브젝트 생성
        HttpHeaders headers = new HttpHeaders();
        headers.add("Authorization", "Bearer " + accessToken);
        headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");

        // HttpHeader와 HttpBody를 하나의 오브젝트에 담기
        RestTemplate rt = new RestTemplate();
        HttpEntity<MultiValueMap<String, String>> kakaoProfileRequest = new HttpEntity<>(headers);

        // Http 요청하기 - Post방식으로 - 그리고 response 변수의 응답 받음.
        ResponseEntity<String> response = rt.exchange(
                "https://kapi.kakao.com/v2/user/me",
                HttpMethod.POST,
                kakaoProfileRequest,
                String.class
        );

        JSONObject body = new JSONObject(response.getBody());
        Long id = body.getLong("id");
        String email = body.getJSONObject("kakao_account").getString("email");
        String nickname = body.getJSONObject("properties").getString("nickname");

        return new KakaoUserInfo(id, email, nickname);
    }
}
profile
Hongik Univ 💻

0개의 댓글