springboot - blog project (64)

Yuri Lee·2020년 9월 3일
0

springboot - blog project

목록 보기
41/49

스프링부트 강좌 64강(블로그 프로젝트) - 카카오 로그인 엑세스토큰 받기


1. 카카오 로그인 버튼 리소스를 다운받아 UI를 완성


2. 카카오 인증 코드 받기

Request URL

GET /oauth/authorize?client_id={REST_API_KEY}&redirect_uri={REDIRECT_URI}&response_type=code HTTP/1.1
Host: kauth.kakao.com

웹 서버 주소 : http://localhost:8080
클라이언트키 : 2170cc08bffc9520b36bca4817118401
카카오 로그인 요청 콜백 주소 : http://localhost:8000/auth/kakao/callback
카카오 로그아웃 요청 콜백 주소 : http://localhost:8000/auth/kakao/logout

로그인 요청 주소 (GET)

https://kauth.kakao.com/oauth/authorize?client_id=2170cc08bffc9520b36bca4817118401&redirect_uri=http://localhost:8000/auth/kakao/callback&response_type=code

응답받은 코드

http://localhost:8000/auth/kakao/callback?code=H6FJ3TV9wGFe2R7MkFK-SArgpKfGBSGhSHg4ake-oU3mNlI53AMSBCcWPI4cUpK8wlm7Nwo9cxcAAAF0VosUzw

	@GetMapping("/auth/kakao/callback")
	public @ResponseBody String kakaoCallback() { //Data를 리턴해주는 컨트롤러 함수
		return "카카오 인증 완료";
	}
	

인증이 완료되었음을 확인하였음.

	@GetMapping("/auth/kakao/callback")
	public @ResponseBody String kakaoCallback(String code) { //Data를 리턴해주는 컨트롤러 함수
		return "카카오 인증 완료 : 코드값" + code;
	}
	

코드값은 받았기 때문에 인증은 완료했다. 이제 인증된 코드값을 통해서 엑세스 코드를 부여받을 것이다. 왜? 카카오 리소스 서버에 등록된 내 개인정보를 응답받기 위해서이다. 그 데이터에 접근하기 위해서 필요한 토큰!


3. 카카오 엑세스 토큰 받기

토큰 발급 요청 주소 (Post) - http body에 데이터를 전달(5가지 데이터를 담아라, 1가지는 필수 X)
MIME : application/x-www-form-urlencoded;charset=utf-8 (key=value)

POST /oauth/token HTTP/1.1
Host: kauth.kakao.com
Content-type: application/x-www-form-urlencoded;charset=utf-8

https://kauth.kako.com/oauth/token

Parameter
grant_type=authorization_code
client_id=2170cc08bffc9520b36bca4817118401
redirect_uri=http://localhost:8000/auth/kakao/callback
code={동적임}
client_secret (필수가 아니므로 제외시킬 것)

package com.yuri.blog.controller;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
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.ResponseBody;
import org.springframework.web.client.RestTemplate;

import com.yuri.blog.config.auth.PrincipalDetail;


// 인증이 안된 사용자들이 출입할 수 있는 경로를 /auth/** 허용
// 그냥 주소가 / 이면 index.jsp 허용 
// static 이하에 있는 /js/**, /css/**, /image/** 

@Controller
public class UserController {

	@GetMapping("/auth/joinForm")
	public String joinForm() {
		return "user/joinForm";
	}
	
	@GetMapping("/auth/loginForm")
	public String loginForm() {
		return "user/loginForm";
	}
	
	@GetMapping("/auth/kakao/callback")
	public @ResponseBody String kakaoCallback(String code) { //Data를 리턴해주는 컨트롤러 함수
		
		// POST 방식으로 key=value 데이터를 요청 (카카오쪽으로), a 태그를 통해서 post 방식 못함, a 태그는 무조건 get 방식임
		// Retrofit2
		// OkHttp
		// RestTemplate
		
		RestTemplate rt = new RestTemplate();
		
		// HttpHeader 오브젝트 생성
		HttpHeaders headers = new HttpHeaders();
		// Content-type에 담는다는 것은  내가 지금 전송한 httpBodydata 가 key value 형태의 데이터라고 알려주는 것
		headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
		
		// HttpBody 오브젝트 생성 
		// Body 데이터를 담을 오브젝트를 만듦, 원래 이런 것들은 변수화를 시켜서 사용하는 것이 좋다. 
		MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
		params.add("grant_type", "authorization_code");
		params.add("client_id", "2170cc08bffc9520b36bca4817118401");
		params.add("redirect_uri", "http://localhost:8000/auth/kakao/callback");
		params.add("code", code);
		
		// HttpHeader 와 HttpBody를 하나의 오브젝트에 담기 
		// kakaoTokenRequest 가 body 데이터와 header 값을 갖고 있는 엔티티가 된다. 
		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
		);
		return "카카오 토큰 요청 완료 : 토큰 요청에 대한 응답 " + response;
	}
	
	
	@GetMapping("/user/updateForm")
	public String updateForm(@AuthenticationPrincipal PrincipalDetail principal) { 
		return "user/updateForm";
	}
}

다음과 같이 카카오 토큰 값을 응답 받았다. 이제 이 응답 받은 값이 어떤 의미인지 궁금할 것

expires_in 토큰에는 만료시간이 있다. 항상 가져올 수 없음. refresh_token 엑세스 토큰을 다시 부여받을 수 있도록 하는 것. 귀찮음을 없애주는.. scope 우리는 이 스코프가 두개이다. 프로필 정보와, 이메일만 접근할 수 있는 스코프이다. 다른 목록도 체크했을 경우 다른 것도 접근 할 수 있을 것이다.

OUTPUT
-{
"access_token" : M3dasc437kXXwy16q-_uIK7LFr2XtPIFdYE62Qo9dNsAAAF0Vs9yXw,
"token_type" : bearer,
"refresh_token" : 6mitPyWWads_NyKvQnkk4Spk72oNghvJfJ5ImQo9dNsAAAF0Vs9yXw,
"expires_in" : 21599,
"scope" : account_email profile,
"refresh_token_expires_in" : 5183999
}


-이 글은 유투버 겟인데어의 스프링 부트 강좌를 바탕으로 정리한 내용입니다.-

profile
Step by step goes a long way ✨

0개의 댓글