์นด์นด์ค ๋ก๊ทธ์ธ ์๋น์ค๋ฅผ ๊ตฌํํ๊ธฐ ์ํด ์นด์นด์ค ๊ฐ๋ฐ์ ์ผํฐ์์ ์ถ๊ฐํ๊ณ , ์ป์ ์ ๋ณด๋ ์๋์ ๊ฐ๋ค.
์นด์นด์ค api
ํด๋ผ์ด์ธํธ ํค : d5526e3b2a4169a3d9f2b7a6f9a12..~~~
์น์๋ฒ์ฃผ์ : http://localhost:8000
์นด์นด์ค ๋ก๊ทธ์ธ์์ฒญ ์ฝ๋ฐฑ ์ฃผ์: http://localhost:8000/auth/kakao/callback
์นด์นด์ค๋ก๋ถํฐ ๋ฐ์ ์ ๋ณด : profile ์ ๋ณด(ํ์) , email(์ ํ)
๋ก๊ทธ์ธ ์์ฒญ ์ฃผ์(GET)
๋ด๊ฐ ์ธ ๊ฒ : https://kauth.kakao.com/oauth/authorize?client_id=d5526e3b2a4169a3d9f2b7a6f9a12cdf&redirect_uri=http://localhost:8000/auth/kakao/callback&response_type=code
์นด์นด์ค ๋ก๊ทธ์ธ ๋ฒํผ์ ์ ์ฃผ์๋ฅผ href ๋ก ๊ฑธ์ด์ฃผ๋ฉด ๋๋ค.
์ด๋๋ ์์ ์ฌ์ง์์ ๋ณผ ์ ์๋ฏ์ด GET ๋ฐฉ์์ด๋ค.
โญ๋ฐ๋ผ์ ์ฃผ์๋ฅผ ํตํด (์ฟผ๋ฆฌ ์คํธ๋ง) ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ค. a ํ๊ทธ!!
< loginForm.jsp >
<a href="https://kauth.kakao.com/oauth/authorize?client_id=d5526e3b2a4169a3d9f2b7a6f9a12cdf&redirect_uri=http://localhost:8000/auth/kakao/callback&response_type=code"><img height="38px" src="/image/kakao_login_button.png" /></a>
์๋ต ๋ฐ์ ์ฝ๋ : http://localhost:8000/auth/kakao/callback?code=04MBIEBh-YAPy8FFBCCoe9h9L_NggQqfavAkjnQgbQ06FYQEbkC_YPG6-UBz9hyZxdBFiQorDKYAAAF_J2OJxg
@GetMapping("/auth/kakao/callback")
public @ResponseBody String kakaoCallback(String code) { // @ResponseBody : Data๋ฅผ ๋ฆฌํดํด์ฃผ๋ ์ปจํธ๋กค๋ฌ ํจ์
return "์นด์นด์ค ์ธ์ฆ ์๋ฃ : ์ฝ๋๊ฐ : " + code;
}
์๋ฅผ ๋ณด๋ฉด code=
ํ๊ณ ์นด์นด์ค API ์๋ฒ๋ก๋ถํฐ code๋ฅผ ๋ฐ์๋ค. ์ฆ, ์ ์์ ์ผ๋ก ์ธ์ฆ์ฒ๋ฆฌ๊ฐ ์๋ฃ ๋์๋ค๋ ๊ฒ์ด๋ค!
์ด์ ์๋ต ๋ฐ์ code ๊ฐ์ ํตํด์ AccessToken ์ ๋ฐ์์ผ ํ๋ค.
์นด์นด์ค ๋ฆฌ์์ค ์๋ฒ์ ๋ฑ๋ก๋ ๋ก๊ทธ์ธ๋ ์ฌ๋์ ์ ๋ณด๋ฅผ ์๋ต๋ฐ๊ธฐ ์ํด์ ์ด๋ค.
์ฆ, ์นด์นด์ค ๋ฆฌ์์ค ์๋ฒ์ ์๋ ํด๋น ์ ๋ณด์ ์ ๊ทผํ ์ ์๋ ๊ถํ์ ์ป์ ์ ์๋ค.
์์ ์ฌ์ง์์ ์ ์ ์๋ฏ์ด POST ๋ฐฉ์์ด๋ค.
โญGET ๋ฐฉ์์ฒ๋ผ ์ฃผ์๋ฅผ ํตํด (์ฟผ๋ฆฌ ์คํธ๋ง) ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๊ฒ์ด ์๋!! http Body์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ค.
ํ ํฐ ๋ฐ๊ธ ์์ฒญ ์ฃผ์ (POST)
MIME : application/x-www-form-urlencoded;charset=utf-8 -> (key=value) ํํ
https://kauth.kakao.com/oauth/token
grant_type = authorization_code
client_id = d5526e3b2a4169a3d9f2b7a6f9a12cdf
redirect_uri = http://localhost:8000/auth/kakao/callback
code = {๋์ }
< UserController >
@GetMapping("/auth/kakao/callback")
public @ResponseBody String kakaoCallback(String code) { // @ResponseBody : Data๋ฅผ ๋ฆฌํดํด์ฃผ๋ ์ปจํธ๋กค๋ฌ ํจ์
// ์นด์นด์ค API ์๋ฒ์๊ฒ POST ๋ฐฉ์์ผ๋ก key=value ๋ฐ์ดํฐ๋ฅผ ์์ฒญ
// ์์ฒญ ๋ฐฉ๋ฒ -> ์ฌ๋ฌ๊ฐ์ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ : HttpsURLConnection, Retrofit2(์ฃผ๋ก ์๋๋ก์ด๋), OkHttp, RestTemplate
RestTemplate rt = new RestTemplate();
// HttpHeader ๊ฐ์ฒด ์์ฑ
HttpHeaders headers = new HttpHeaders();
headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8"); // key=value ํํ์ ๋ฐ์ดํฐ๋ผ๋ ๊ฒ์ ์๋ ค์ฃผ๋ ๋ถ๋ถ
// HttpBody ๊ฐ์ฒด ์์ฑ
MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
params.add("grant_type", "authorization_code");
params.add("client_id", "d5526e3b2a4169a3d9f2b7a6f9a12cdf");
params.add("redirect_uri", "http://localhost:8000/auth/kakao/callback");
params.add("code", code);
// HttpHeader์ HttpBody๋ฅผ ํ๋์ ๊ฐ์ฒด์ ๋ด๊ธฐ -> ๋ง๋ ์ด์ : ์๋์ exchange ํจ์์ HttpEntity๋ฅผ ๋ฃ์ด์ผ ํด์..
HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest =
new HttpEntity<>(params, headers); // body ๋ฐ์ดํฐ์ headers ๊ฐ์ ๊ฐ์ง๊ณ ์๋ Entity
// ์นด์นด์ค์๊ฒ Http ์์ฒญํ๊ธฐ (POST ๋ฐฉ์) -> response๋ผ๋ ๋ณ์์ ์๋ต์ ๋ฐ์
ResponseEntity<String> response = rt.exchange(
"https://kauth.kakao.com/oauth/token",
HttpMethod.POST,
kakaoTokenRequest,
String.class
);
// return "์นด์นด์ค ์ธ์ฆ ์๋ฃ : ์ฝ๋๊ฐ : " + code;
return "์นด์นด์ค ํ ํฐ ์์ฒญ ์๋ฃ : ํ ํฐ์์ฒญ์ ๋ํ ์๋ต : " + response;
}
์์ ์ฝ๋๋ ์์ฒญ ๋ฐฉ๋ฒ์ด๋ค.
RestTemplate ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๊ณ , HttpHeader ๊ฐ์ฒด ์์ฑ, HttpBody ๊ฐ์ฒด ์์ฑ, Http ์์ฒญ๊น์ง ์ฐจ๋ก๋๋ก ๊ตฌํํ๋ค.
์๋ต์ด ์ด๋ ๊ฒ ์๋ค!!
์์์ ์์ฒญ์ ๋ํ ์๋ต ๋ด์ฉ์ ๋ฏ์ด๋ณด์!
์นด์นด์ค ํ ํฐ ์์ฒญ ์๋ฃ : ํ ํฐ์์ฒญ์ ๋ํ ์๋ต : <200,{"access_token":"0gFpYkxJJHa3BNFx1ZZn3XvKjCHjJHYBpHxh2go9dJcAAAF_J7AhMA","token_type":"bearer","refresh_token":"Esq-jTYjpVt_R5_gRWAR04ZVoqewddpfbMyZ2Ao9dJcAAAF_J7AhLg","expires_in":21599,"scope":"account_email profile_image profile_nickname","refresh_token_expires_in":5183999},[Date:"Wed, 23 Feb 2022 17:45:28 GMT", Content-Type:"application/json;charset=utf-8", Transfer-Encoding:"chunked", Connection:"keep-alive", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-XSS-Protection:"1; mode=block", X-Frame-Options:"DENY", X-Content-Type-Options:"nosniff", Kakao:"Talk", Access-Control-Allow-Origin:"*", Access-Control-Allow-Methods:"GET, POST, OPTIONS", Access-Control-Allow-Headers:"Authorization, KA, Origin, X-Requested-With, Content-Type, Accept"]>
200์ ์์ฒญ์ฑ๊ณต ์ด๋ค !
scope ๋ ๋ด๊ฐ ๊ฐ์ธ์ ๋ณด ๋์ ํญ๋ชฉ์ ์ค์ ํ ๋, ํ๋กํ ์ ๋ณด(๋๋ค์/ํ๋กํ์ฌ์ง) ๊ณผ ์นด์นด์ค๊ณ์ (์ด๋ฉ์ผ) ๋ง ๋์๋ฅผ ํด๋จ๊ธฐ ๋๋ฌธ์ ์์ฒ๋ผ ์๋ต์ด ๋๋ค.
์๋ต์ด json ๊ฐ์ฒด๋ก ์์ผ๋ ์ด๋ฅผ ์ฝ๊ฒ ํ์ธํ๊ธฐ ์ํด Parser๋ก ๋ณด์๋ค.
<์ด๋ฒ ๊ฒ์๊ธ์์ ์ฌ์ฉํ ์ ๋ณด๋ค>