[Spring] ์นด์นด์˜ค ๋กœ๊ทธ์ธ API ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•

2024. 2. 7. 09:41ใ†Spring/[2024] Spring Boot

728x90

 

 

์š”์ฆ˜์€ ์นด์นด์˜ค, ๋„ค์ด๋ฒ„๋ฅผ ์ด์šฉํ•œ Login Api ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค. 

์‹ค์ œ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ์ƒ˜ํ”Œ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด kakao login api ๋™์ž‘ ๋ฐฉ์‹์„ ์•Œ์•„๋ณผ ๊ฒƒ์ด๋‹ค. 

REST API๋ฅผ ์‚ฌ์šฉํ•œ ์นด์นด์˜ค ๋กœ๊ทธ์ธ์€ PC ๋ฐ ๋ชจ๋ฐ”์ผ ์›น์—์„œ ์ ํ•ฉํ•œ ๋ฐฉ์‹์ด๋‹ค. 

 

์นด์นด์˜ค ๋กœ๊ทธ์ธ์€ OAuth 2.0 ๊ธฐ๋ฐ˜์˜ ์†Œ์…œ ๋กœ๊ทธ์ธ ์„œ๋น„์Šค๋กœ ์นด์นด์˜ค ๋กœ๊ทธ์ธ์„ ์ด์šฉํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์นด์นด์˜คํ†ก ๋˜๋Š” ์นด์นด์˜ค ๊ณ„์ •์œผ๋กœ ์†์‰ฝ๊ฒŒ ์„œ๋น„์Šค์— ๋กœ๊ทธ์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

์นด์นด์˜ค ๋กœ๊ทธ์ธ ์„œ๋น„์Šค ๊ณผ์ • 

 

1๏ธโƒฃ ์นด์นด์˜ค ๋กœ๊ทธ์ธ 

  1. ์‚ฌ์šฉ์ž๊ฐ€ ์„œ๋น„์Šค์—์„œ ์นด์นด์˜ค ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค. ์„œ๋น„์Šค๋Š” ์นด์นด์˜ค ์ธ์ฆ ์„œ๋ฒ„๋กœ ์ธ๊ฐ€ ์ฝ”๋“œ ๋ฐœ๊ธ‰์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
  2. ์นด์นด์˜ค ์ธ์ฆ ์„œ๋ฒ„๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ์ธ์ฆ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. (์ฐธ๊ณ : ์‚ฌ์šฉ์ž ํ™˜๊ฒฝ์— ๋”ฐ๋ฅธ ์ธ์ฆ ๋ฐฉ๋ฒ•)
    • ์นด์นด์˜คํ†ก์œผ๋กœ ๋กœ๊ทธ์ธ: ์นด์นด์˜คํ†ก ์‹คํ–‰, ์นด์นด์˜คํ†ก์— ์—ฐ๊ฒฐ๋œ ์นด์นด์˜ค๊ณ„์ •์˜ ์ž๊ฒฉ์ •๋ณด(Credentials)๋กœ ์‚ฌ์šฉ์ž ์ธ์ฆ
    • ์นด์นด์˜ค๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธ: ๊ณ„์ • ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•ด ๋กœ๊ทธ์ธํ•˜๋Š” ํ™”๋ฉด ์ถœ๋ ฅ, ํ•ด๋‹น ์นด์นด์˜ค๊ณ„์ •์˜ ์ž๊ฒฉ์ •๋ณด๋กœ ์‚ฌ์šฉ์ž ์ธ์ฆ
  3. ์นด์นด์˜ค ์ธ์ฆ ์„œ๋ฒ„๋Š” ์‚ฌ์šฉ์ž ์ธ์ฆ ์„ฑ๊ณต ์‹œ, ์„œ๋น„์Šค ์•ฑ์˜ ๋™์˜ํ•ญ๋ชฉ ์„ค์ •์„ ๋ฐ”ํƒ•์œผ๋กœ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋™์˜ ํ™”๋ฉด์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
  4. ์‚ฌ์šฉ์ž๊ฐ€ ํ•„์ˆ˜ ๋™์˜ํ•ญ๋ชฉ์— ๋™์˜ํ•˜๊ณ  ๋กœ๊ทธ์ธ์„ ์š”์ฒญํ•˜๋ฉด, ์นด์นด์˜ค ์ธ์ฆ ์„œ๋ฒ„๋Š” ์ธ๊ฐ€ ์ฝ”๋“œ(Authorization Code)๋ฅผ ๋ฐœ๊ธ‰ํ•ด ์„œ๋น„์Šค ์•ฑ์— ๋“ฑ๋ก๋œ Redirect URI๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  5. ์„œ๋น„์Šค๋Š” ์ „๋‹ฌ๋ฐ›์€ ์ธ๊ฐ€ ์ฝ”๋“œ๋กœ ํ† ํฐ์„ ์š”์ฒญํ•˜์—ฌ ๋ฐ›์Šต๋‹ˆ๋‹ค.

 

2๏ธโƒฃ ํšŒ์› ํ™•์ธ ๋ฐ ๊ฐ€์ž… 

  1. ์„œ๋น„์Šค๋Š” ์นด์นด์˜ค ๋กœ๊ทธ์ธ์„ ์™„๋ฃŒํ•˜์—ฌ ๋ฐœ๊ธ‰๋ฐ›์€ ํ† ํฐ์œผ๋กœ ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.
  2. ์นด์นด์˜ค API ์„œ๋ฒ„๋Š” ์š”์ฒญ ์‹œ ์‚ฌ์šฉ๋œ ํ† ํฐ์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์ฆํ•˜๊ณ , ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ณ  ์„œ๋น„์Šค์— ์‘๋‹ตํ•ฉ๋‹ˆ๋‹ค.
  3. ์„œ๋น„์Šค ์„œ๋ฒ„๋Š” ์นด์นด์˜ค๋กœ๋ถ€ํ„ฐ ์ œ๊ณต๋ฐ›์€ ์‚ฌ์šฉ์ž ์ •๋ณด๋กœ ํ•ด๋‹น ์‚ฌ์šฉ์ž๊ฐ€ ์„œ๋น„์Šค์— ํšŒ์› ๊ฐ€์ž…๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
    • ์ด๋ฏธ ํšŒ์› ๊ฐ€์ž…๋œ ์‚ฌ์šฉ์ž: Step 3์˜ ์„œ๋น„์Šค ๋กœ๊ทธ์ธ ๋‹จ๊ณ„ ์ˆ˜ํ–‰
    • ์•„์ง ํšŒ์› ๊ฐ€์ž…๋˜์ง€ ์•Š์€ ์‚ฌ์šฉ์ž: ์นด์นด์˜ค์—์„œ ์ œ๊ณต๋ฐ›์€ ์‚ฌ์šฉ์ž ์ •๋ณด๋กœ ์„œ๋น„์Šค ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ํšŒ์› ๊ฐ€์ž… ์ฒ˜๋ฆฌ

-> ์นด์นด์˜ค๊ฐ€ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ํšŒ์› ์ •๋ณด๋ฅผ ๋Œ€์‹  ์ €์žฅํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์—  ์ด๋•Œ ํšŒ์› ์ •๋ณด ์ฒ˜๋ฆฌ๋Š” ์„œ๋น„์Šค์—์„œ ์ž์ฒด ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค. 

 

3๏ธโƒฃ ์„œ๋น„์Šค ๋กœ๊ทธ์ธ 

  1. ์„œ๋น„์Šค ์„œ๋ฒ„๋Š” ์„œ๋น„์Šค ํด๋ผ์ด์–ธํŠธ์— ํ•ด๋‹น ์‚ฌ์šฉ์ž์˜ ๋กœ๊ทธ์ธ์— ๋Œ€ํ•œ ์„ธ์…˜์„ ๋ฐœ๊ธ‰ํ•ฉ๋‹ˆ๋‹ค.
    • OpenID Connect ์‚ฌ์šฉ ์‹œ: ํ† ํฐ๊ณผ ํ•จ๊ป˜ ๋ฐœ๊ธ‰๋œ ID ํ† ํฐ์œผ๋กœ ์„œ๋น„์Šค ๋กœ๊ทธ์ธ ์„ธ์…˜์„ ๋Œ€์‹ ํ•  ์ˆ˜ ์žˆ์Œ
  2. ์„œ๋น„์Šค ํด๋ผ์ด์–ธํŠธ๋Š” ์„œ๋น„์Šค ์„ธ์…˜์„ ์ „๋‹ฌ๋ฐ›์•„ ๋กœ๊ทธ์ธ ์™„๋ฃŒ ์ฒ˜๋ฆฌํ•˜๊ณ , ์‚ฌ์šฉ์ž๋ฅผ ๋กœ๊ทธ์ธ๋œ ์„œ๋น„์Šค ํ™”๋ฉด์œผ๋กœ ์ด๋™์‹œํ‚ต๋‹ˆ๋‹ค.

 

 

 

์นด์นด์˜ค ๋กœ๊ทธ์ธ ์„œ๋น„์Šค ์‚ฌ์ „ ์„ค์ • 

https://developers.kakao.com/

 

Kakao Developers

์นด์นด์˜ค API๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•ด๋ณด์„ธ์š”. ์นด์นด์˜ค ๋กœ๊ทธ์ธ, ๋ฉ”์‹œ์ง€ ๋ณด๋‚ด๊ธฐ, ์นœ๊ตฌ API, ์ธ๊ณต์ง€๋Šฅ API ๋“ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

developers.kakao.com

-> ๋จผ์ € ์นด์นด์˜ค ๊ฐœ๋ฐœ์ž ์‚ฌ์ดํŠธ์— ๊ฐ€์„œ ๋กœ๊ทธ์ธ ํ›„ ๋‚ด๊ฐ€ ๊ฐœ๋ฐœํ•  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋“ฑ๋กํ•ด์ค˜์•ผ ํ•œ๋‹ค. 

 

 

1๏ธโƒฃ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ถ”๊ฐ€ํ•˜๊ธฐ

์—ฌ๊ธฐ์— ๊ฐ์ž ๋กœ๊ทธ์ธ ์„œ๋น„์Šค๋ฅผ ํ•  ์•ฑ ์ด๋ฆ„, ์‚ฌ์—…์ž๋ช…, ์นดํ…Œ๊ณ ๋ฆฌ ๋“ฑ์„ ์ž‘์„ฑํ•ด์ค€๋‹ค. 

๋‚˜๋Š” ํ…Œ์ŠคํŠธํ•  ์šฉ๋„์ด๊ธฐ ๋•Œ๋ฌธ์— ์ž์„ธํžˆ ์ ์ง€๋Š” ์•Š์•˜๋‹ค..! 

 

 

2๏ธโƒฃ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ถ”๊ฐ€ ํ›„ Rest API ํ‚ค ํ™•์ธํ•˜๊ธฐ

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ถ”๊ฐ€ ํ›„ [์š”์•ฝ ์ •๋ณด] ํŽ˜์ด์ง€๋ฅผ ํ™•์ธํ•˜๋ฉด REST API ์•ฑ ํ‚ค๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

 

3๏ธโƒฃ Web ํ”Œ๋žซํผ ๋“ฑ๋กํ•˜๊ธฐ

 

-> [ํ”Œ๋žซํผ] ํŽ˜์ด์ง€์— Web ํ”Œ๋žซํผ ๋“ฑ๋ก์„ ํด๋ฆญํ•˜๋ฉด 

์ด๋ ‡๊ฒŒ ๋„๋ฉ”์ธ ๋“ฑ๋กํ•˜๋Š” ํŒ์—…์ด ๋‚˜์˜จ๋‹ค. 

๋‚˜๋Š” ํ…Œ์ŠคํŠธํ•˜๋Š” ํ”„๋กœ์ ํŠธ์ด๊ธฐ ๋•Œ๋ฌธ์— http://localhost:8080 ์œผ๋กœ ๋“ฑ๋กํ–ˆ๋‹ค. ใ…Žใ…Ž 

 

 

๊ทธ ๋‹ค์Œ ์นด์นด์˜ค ๋กœ๊ทธ์ธ ์‚ฌ์šฉ ์‹œ ์ฝœ๋ฐฑ ๋ฐ›์„ Redirect URI ๋ฅผ ๋“ฑ๋กํ•ด์•ผ ํ•œ๋‹ค. 

 

 

-> ๊ทธ ์ „์— [์นด์นด์˜ค ๋กœ๊ทธ์ธ] ํŽ˜์ด์ง€์—์„œ ์นด์นด์˜ค ๋กœ๊ทธ์ธ ํ™œ์„ฑํ™”๋ฅผ on ํ•ด์ฃผ๊ณ , Redirect URI๋ฅผ ๋“ฑ๋กํ•ด์ค€๋‹ค. 

 

์—ฌ๊ธฐ์—๋Š” ๊ฐ์ž ๊ฐœ๋ฐœํ•  Redirect URI๋ฅผ ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๋œ๋‹ค. 

๋‚˜๋Š” http://localhost:8080/login/kakao/code ๋กœ ๋“ฑ๋กํ•ด์คฌ๋‹ค. 

 

 

4๏ธโƒฃ ๋™์˜ ํ•ญ๋ชฉ ์„ค์ •

-> ์•„๋งˆ ๋น„์ฆˆ์•ฑ ์‹ ์ฒญ์•ˆํ•˜๋ฉด ๋‹ค๋ฅธ ์ •๋ณด๋“ค์€ ๊ถŒํ•œ์ด ์—†์–ด์„œ ๋‹‰๋„ค์ž„, ํ”„๋กœํ•„ ์‚ฌ์ง„๋งŒ ํ•„์ˆ˜๋กœ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. 

 

* ์ถ”๊ฐ€๋กœ ์นด์นด์˜ค ๋กœ๊ทธ์ธ ์ด๋ฏธ์ง€ ๋ฒ„ํŠผ ๋‹ค์šด๋ฐ›๊ธฐ 

์ด๋ ‡๊ฒŒ ๋กœ๊ทธ์ธ ์ด๋ฏธ์ง€ ๋ฒ„ํŠผ์„ ๋‹ค์šด ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. 

 

-> ๋กœ๊ทธ์ธ ์ด๋ฏธ์ง€ ๋ฒ„ํŠผ๊นŒ์ง€ ๋ฐ›์•˜๋‹ค๋ฉด kakao Devleopers์—์„œ ์„ค์ •ํ•  ๊ฑด ๋๋‚ฌ๋‹ค. 

 

* ์นด์นด์˜ค ๋กœ๊ทธ์ธ REST API ๋ฌธ์„œ 

https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api

 

Kakao Developers

์นด์นด์˜ค API๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•ด๋ณด์„ธ์š”. ์นด์นด์˜ค ๋กœ๊ทธ์ธ, ๋ฉ”์‹œ์ง€ ๋ณด๋‚ด๊ธฐ, ์นœ๊ตฌ API, ์ธ๊ณต์ง€๋Šฅ API ๋“ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

developers.kakao.com

 

 

 

์นด์นด์˜ค ๋กœ๊ทธ์ธ ์ƒ˜ํ”Œ ํ”„๋กœ์ ํŠธ ๋งŒ๋“ค๊ธฐ 

์นด์นด์˜ค ๋กœ๊ทธ์ธ ๊ณผ์ • โœ”
1. ์ธ๊ฐ€ ์ฝ”๋“œ ๋ฐ›๊ธฐ 
2. ํ† ํฐ ๋ฐ›๊ธฐ 
3. ํ† ํฐ์œผ๋กœ ์‚ฌ์šฉ์ž ์ •๋ณด ์–ป๊ธฐ 

 

 

1๏ธโƒฃ ์ธ๊ฐ€ ์ฝ”๋“œ ๋ฐ›๊ธฐ 

์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด https://kauth.kakao.com/oauth/authorize ์ด URL๋กœ ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ์š”์ฒญํ•œ๋‹ค. 
๊ทธ๋Ÿฌ๋ฉด ์นด์นด์˜ค ์ธ์ฆ ์„œ๋ฒ„๋Š” ์นด์นด์˜ค ๋กœ๊ทธ์ธ ๋™์˜ ํ™”๋ฉด์„ ํ˜ธ์ถœํ•˜๊ณ , ์‚ฌ์šฉ์ž ๋™์˜๋ฅผ ๊ฑฐ์ณ ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ๋ฐœ๊ธ‰ํ•œ๋‹ค. 

์ด๋•Œ ๋™์˜ ํ™”๋ฉด์€ ์œ„์—์„œ ์„ค์ •ํ•œ ๋™์˜ ํ•ญ๋ชฉ์— ๋Œ€ํ•ด ์‚ฌ์šฉ์ž์—๊ฒŒ ์ธ๊ฐ€(๋™์˜)๋ฅผ ๊ตฌํ•œ๋‹ค. 

 

์ธ๊ฐ€ ์ฝ”๋“œ๋Š” ๋™์˜ ํ™”๋ฉด์„ ํ†ตํ•ด ์ธ๊ฐ€๋ฐ›์€ ๋™์˜ํ•ญ๋ชฉ ์ •๋ณด๋ฅผ ๊ฐ–๊ณ  ์žˆ๊ณ , ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•ด ํ† ํฐ ๋ฐ›๊ธฐ๋ฅผ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

โœ” ๊ทธ๋ฆฌ๊ณ  ์ด๋•Œ ๋™์˜ํ™”๋ฉด์€ ์‚ฌ์šฉ์ž์™€ ์•ฑ์ด ์ฒ˜์Œ ์—ฐ๊ฒฐ๋  ๋•Œ๋งŒ ๋‚˜ํƒ€๋‚œ๋‹ค! 
์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฏธ ๋™์˜ ํ™”๋ฉด์—์„œ ์„œ๋น„์Šค ์ด์šฉ์— ํ•„์š”ํ•œ ๋™์˜ํ•ญ๋ชฉ์— ๋™์˜ ์™„๋ฃŒํ•œ ๊ฒฝ์šฐ, ํ•ด๋‹น ์‚ฌ์šฉ์ž์˜ ์นด์นด์˜ค ๋กœ๊ทธ์ธ ์‹œ์—๋Š” ๋™์˜ ํ™”๋ฉด์ด ๋‚˜ํƒ€๋‚˜์ง€ ์•Š๊ณ  ์ฆ‰์‹œ ์ธ๊ฐ€ ์ฝ”๋“œ๊ฐ€ ๋ฐœ๊ธ‰๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž์™€ ์•ฑ์ด ์—ฐ๊ฒฐ๋œ ์ดํ›„ ๋‹ค์‹œ ๋™์˜ ํ™”๋ฉด์„ ํ†ตํ•ด ํŠน์ • ๋™์˜ํ•ญ๋ชฉ์— ๋Œ€ํ•œ ์‚ฌ์šฉ์ž ๋™์˜๋ฅผ ์š”์ฒญํ•˜๋ ค๋ฉด ์ถ”๊ฐ€ ํ•ญ๋ชฉ ๋™์˜ ๋ฐ›๊ธฐ๋กœ ๋™์˜ ํ™”๋ฉด์„ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋น„์Šค ๊ฐ€์ž… ๊ณผ์ •์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์™„๋ฃŒ๋˜์ง€ ์•Š์•„ ๋‹ค์‹œ ๋™์˜ ํ™”๋ฉด์„ ํ˜ธ์ถœํ•ด์•ผ ํ•  ๊ฒฝ์šฐ์—๋Š” ์—ฐ๊ฒฐ ๋Š๊ธฐ ํ›„ ๋‹ค์‹œ ์ธ๊ฐ€ ์ฝ”๋“œ ๋ฐ›๊ธฐ๋ฅผ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์„œ ์ด์ œ ์‚ฌ์šฉ์ž๊ฐ€ ๋ชจ๋“  ํ•„์ˆ˜ ๋™์˜ํ•ญ๋ชฉ์„ ๋™์˜ํ•˜๊ณ  [๋™์˜ํ•˜๊ณ  ๊ณ„์†ํ•˜๊ธฐ] ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด 

-> redirect_uri๋กœ ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ๋‹ด์€ ์ฟผ๋ฆฌ ์ŠคํŠธ๋ง ์ „๋‹ฌํ•˜๊ณ , 

 

[์ทจ์†Œ] ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ ๋กœ๊ทธ์ธ ์ทจ์†Œํ•˜๋ฉด 

-> redirect_uri๋กœ ์—๋Ÿฌ ์ •๋ณด๋ฅผ ๋‹ด์€ ์ฟผ๋ฆฌ ์ŠคํŠธ๋ง ์ „๋‹ฌํ•œ๋‹ค. 

 

์š”์ฒญ ์ฟผ๋ฆฌํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ๋ฐ‘์— url์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. 

https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#request-code-request-query

 

Kakao Developers

์นด์นด์˜ค API๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•ด๋ณด์„ธ์š”. ์นด์นด์˜ค ๋กœ๊ทธ์ธ, ๋ฉ”์‹œ์ง€ ๋ณด๋‚ด๊ธฐ, ์นœ๊ตฌ API, ์ธ๊ณต์ง€๋Šฅ API ๋“ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

developers.kakao.com

 

-> ๊ทธ ์ค‘ ํ•„์ˆ˜๋Š” client_id, redirect_uri, response_type ์ด๋ ‡๊ฒŒ 3๊ฐ€์ง€ ์ด๋‹ค. 

 

application-private.yml 

kakao:
  api_key: 
  redirect_uri:

-> application-private.yml์— ์นด์นด์˜ค ๊ฐœ๋ฐœ์ž ์‚ฌ์ดํŠธ์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋“ฑ๋ก ํ›„ ๋ฐ›์€ REST API ์•ฑ ํ‚ค์™€ ์„ค์ •ํ•œ Redirect_uri๋ฅผ ๋‹ด์•„์„œ ๋”ฐ๋กœ ๊ด€๋ฆฌํ•ด์ค€๋‹ค. 

 

application.yml 

spring:
  profiles:
    include: private

-> ๊ทธ๋ฆฌ๊ณ  application.yml์— private yml์„ ํฌํ•จํ•˜๋„๋ก ํ•œ๋‹ค. 

 

KakaoApi 

@Slf4j
@Getter
@Component
public class KaKaoApi
{
    @Value("${kakao.api_key}")
    private String kakaoApiKey;
    
    @Value("${kakao.redirect_uri}")
    private String kakaoRedirectUri;
    
}

-> application-private.yml์— ๊ฐ’์„ ๋‹ด๋Š” vo๋ฅผ ๋งŒ๋“ค์–ด์ค€๋‹ค. 

 

 

TestController 

    @GetMapping("/login")
    public String loginForm(Model model)
    {
       model.addAttribute("kakaoApiKey", kaKaoApi.getKakaoApiKey());
       model.addAttribute("kakaoRedirectUri", kaKaoApi.getKakaoRedirectUri());
       return "login";
    }

-> kakaoApi ๋ฅผ ์ž๋™ ์ฃผ์ž…๋ฐ›์•„์„œ kakaoApikey์™€ kakaoRedirectUri๋ฅผ login ํŽ˜์ด์ง€์— ๋‹ด์•„ ๋„˜๊ธด๋‹ค. 

 

 

login.html 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Kakao & Naver Login API TEST</title>
</head>
<body>
<div class="text-center">
    <a href="https://kauth.kakao.com/oauth/authorize"
       th:href="@{https://kauth.kakao.com/oauth/authorize(client_id=${kakaoApiKey}, redirect_uri=${kakaoRedirectUri}, response_type='code')}">
        <img src="/images/kakao_login_medium_narrow.png">
    </a>
</div>
</body>
</html>

 

-> ๋งจ ์ฒ˜์Œ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€์ด๋‹ค. ์ด ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด https://kauth.kakao.com/oauth/authorize ์ด url๋กœ client_id, redierct_uri, response_type ๊ฐ’์„ ๋‹ด์•„์„œ ์š”์ฒญํ•œ๋‹ค. ์ด๋•Œ response_type ์—๋Š” code๋กœ ๊ณ ์ •ํ•ด์„œ ๋ณด๋‚ธ๋‹ค. 

 

-> ๊ทธ๋Ÿฌ๋ฉด ์‘๋‹ต๊ฐ’์œผ๋กœ ํ† ํฐ ๋ฐ›๊ธฐ ์š”์ฒญ์— ํ•„์š”ํ•œ code๋ฅผ redirect_uri์— ๋‹ด์•„ ์ „๋‹ฌํ•œ๋‹ค. 

 

 

2๏ธโƒฃ ํ† ํฐ ๋ฐ›๊ธฐ 

์ด์ œ ๋ฐ›์€ ์ธ๊ฐ€ ์ฝ”๋“œ๋กœ ํ† ํฐ ๋ฐœ๊ธ‰์„ ์š”์ฒญํ•ด์•ผ ํ•œ๋‹ค. ์ธ๊ฐ€ ์ฝ”๋“œ ๋ฐ›๊ธฐ๋งŒ์œผ๋กœ๋Š” ์นด์นด์˜ค ๋กœ๊ทธ์ธ์ด ์™„๋ฃŒ๋˜์ง€ ์•Š๋Š”๋‹ค. ํ† ํฐ ๋ฐ›๊ธฐ ๊นŒ์ง€ ๋งˆ์ณ์•ผ ๋กœ๊ทธ์ธ์„ ์ •์ƒ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

ํ•„์ˆ˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ํฌํ•จํ•ด์„œ https://kauth.kakao.com/oauth/token ์— POST๋กœ ์š”์ฒญํ•œ๋‹ค. 

์š”์ฒญ ์„ฑ๊ณต์‹œ ์‘๋‹ต์€ ํ† ํฐ๊ณผ ํ† ํฐ ์ •๋ณด๋ฅผ ํฌํ•จํ•ด์„œ ๋ฐ˜ํ™˜ํ•œ๋‹ค. 

 

๊ทธ๋ฆฌ๊ณ  ์ด ๋ฐ›์€ ์•ก์„ธ์Šค ํ† ํฐ์œผ๋กœ ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ API ๋ฅผ ํ˜ธ์ถœํ•ด ํ•„์š”ํ•œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๋ฐ›์•„ ์„œ๋น„์Šค ํšŒ์› ๊ฐ€์ž… ๋ฐ ๋กœ๊ทธ์ธ์„ ์™„๋ฃŒํ•ด์•ผ ํ•œ๋‹ค.

 

KakaoApi

public String getAccessToken(String code)
{
    String reqUrl = "https://kauth.kakao.com/oauth/token";
    RestTemplate restTemplate = new RestTemplate();
    
    // HttpHeader Object
    HttpHeaders headers = new HttpHeaders();
    headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
    
    // HttpBody Object
    MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
    params.add("grant_type", "authorization_code");
    params.add("client_id", kakaoApiKey);
    params.add("redirect_uri", kakaoRedirectUri);
    params.add("code", code);
    
    // http ๋ฐ”๋”” params ์™€ http ํ—ค๋” headers ๋ฅผ ๊ฐ€์ง„ ์—”ํ‹ฐํ‹ฐ
    HttpEntity<MultiValueMap<String, String>> kakaoTokenRequest = new HttpEntity<>(params, headers);
    
    // reqUrl ๋กœ Http ์š”์ฒญ, POST ๋ฐฉ์‹
    ResponseEntity<String> response = restTemplate.exchange(reqUrl,
                                              HttpMethod.POST,
                                              kakaoTokenRequest,
                                              String.class);
    
    String responseBody = response.getBody();
    JsonObject asJsonObject = JsonParser.parseString(responseBody).getAsJsonObject();
    
    return asJsonObject.get("access_token").getAsString();
}

-> https://kauth.kakao.com/oauth/token ์— ๋ฐ›์€ grant_type์€ authorization_code๋กœ ๊ณ ์ •ํ•˜๊ณ , client_id, redirect_uri, code ๋ฅผ ๋‹ด์•„ post๋กœ ์š”์ฒญํ•œ๋‹ค. 

 

์ด๋•Œ ๋ฐ˜๋“œ์‹œ Content-type์€ application/x-www-form-urlencoded;charset=utf-8 ๋กœ ๋ณด๋‚ด์•ผํ•œ๋‹ค!!!! ์•„๋‹ˆ๋ฉด ์—๋Ÿฌ๋‚จ ใ…Žใ…Ž 

 

์ด๋ ‡๊ฒŒ ์š”์ฒญํ•˜๋ฉด ์‘๋‹ต์œผ๋กœ 

์‚ฌ์šฉ์ž ์—‘์„ธ์Šค ํ† ํฐ ๊ฐ’์„ ์ „๋‹ฌ๋ฐ›๋Š”๋‹ค. 

 

3๏ธโƒฃ ์‚ฌ์šฉ์ž ์ •๋ณด ๊ฐ€์ ธ์˜ค๊ธฐ 

์ด ์—‘์„ธ์Šค ํ† ํฐ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ํ˜„์žฌ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์™€์„œ ์ด ์‚ฌ์šฉ์ž๊ฐ€ ์šฐ๋ฆฌ ์„œ๋น„์Šค ๊ฐ€์ž…ํ•œ ํšŒ์›์ธ์ง€, ์•„๋‹Œ์ง€ ๋น„๊ต ํ›„ ์—†๋Š” ์‚ฌ์šฉ์ž๋ฉด ํšŒ์› ๊ฐ€์ž…์„ ์ง„ํ–‰ํ•˜๊ณ , ์žˆ๋Š” ์‚ฌ์šฉ์ž๋ฉด ์ •๋ณด ๋น„๊ต ํ›„ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ๋ฅผ ์™„๋ฃŒํ•˜๋ฉด ๋œ๋‹ค. 

 

KakaoApi 

public KakaoProfile getUserInfo(String accessToken) {
    String reqUrl = "https://kapi.kakao.com/v2/user/me";
    
    RestTemplate restTemplate = new RestTemplate();
    
    //HttpHeader ์˜ค๋ธŒ์ ํŠธ
    HttpHeaders headers = new HttpHeaders();
    headers.add("Authorization", "Bearer " + accessToken);
    headers.add("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
    
    //http ํ—ค๋”(headers)๋ฅผ ๊ฐ€์ง„ ์—”ํ‹ฐํ‹ฐ
    HttpEntity<MultiValueMap<String, String>> kakaoProfileRequest = new HttpEntity<>(headers);
    
    //reqUrl๋กœ Http ์š”์ฒญ , POST ๋ฐฉ์‹
    ResponseEntity<String> response = restTemplate.exchange(reqUrl, HttpMethod.POST, kakaoProfileRequest, String.class);
    
    KakaoProfile kakaoProfile = new KakaoProfile(response.getBody());
    
    return kakaoProfile;
}

-> https://kapi.kakao.com/v2/user/me ๋กœ ์‚ฌ์šฉ์ž ์—‘์„ธ์Šค ํ† ํฐ์„ Authorization์— ๋‹ด์•„์„œ  POST ๋กœ ์š”์ฒญํ–ˆ๋‹ค. 

 

์š”์ฒญ์— ์„ฑ๊ณตํ•˜๋ฉด ์ด์ œ ์‘๋‹ต์— ์ด์ œ ์นด์นด์˜ค ๊ณ„์ • ์ •๋ณด๋ฅผ ๋‹ด์•„์ค€๋‹ค. 

 

*kakao_account์— ๋Œ€ํ•œ ์ •๋ณด

https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#kakaoaccount

 

Kakao Developers

์นด์นด์˜ค API๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•ด๋ณด์„ธ์š”. ์นด์นด์˜ค ๋กœ๊ทธ์ธ, ๋ฉ”์‹œ์ง€ ๋ณด๋‚ด๊ธฐ, ์นœ๊ตฌ API, ์ธ๊ณต์ง€๋Šฅ API ๋“ฑ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

developers.kakao.com

 

 

KakaoProfile

@Getter
public class KakaoProfile {
    private Integer id;
    private LocalDateTime connectedAt;
    private String nickname;
    
    public KakaoProfile(String jsonResponseBody){
       JsonParser parser = new JsonParser();
       JsonElement element = parser.parse(jsonResponseBody);
       
       this.id = element.getAsJsonObject().get("id").getAsInt();
       
       String connected_at = element.getAsJsonObject().get("connected_at").getAsString();
       connected_at = connected_at.substring(0, connected_at.length() - 1);
       LocalDateTime connectDateTime = LocalDateTime.parse(connected_at, DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss"));
       this.connectedAt = connectDateTime;
       
       JsonObject properties = element.getAsJsonObject().get("properties").getAsJsonObject();
       this.nickname = properties.getAsJsonObject().get("nickname").getAsString();
       
    }
    
}

๋ฐ›์€ response body๋ฅผ KakaoProfile ์ด๋ผ๋Š” vo๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์„œ ํšŒ์› ๋ฒˆํ˜ธ, ์„œ๋น„์Šค์— ์—ฐ๊ฒฐ๋œ ์‹œ๊ฐ, ๋‹‰๋„ค์ž„ ๋“ฑ์˜ ์ •๋ณด๋ฅผ ๋„ฃ์–ด์คฌ๋‹ค. 

 

TestController 

@ResponseBody
@GetMapping("/login/kakao/code")
public Map<String, Object> kakaoLogin(@RequestParam String code)
{
    Map<String, Object> map = new HashMap<>();
    // 1. ์ธ๊ฐ€ ์ฝ”๋“œ ๋ฐ›๊ธฐ -> @RequestParam String code
    
    // 2. ํ† ํฐ ๋ฐ›๊ธฐ
    String accessToken = String.valueOf(kaKaoApi.getAccessToken(code));
    
    // 3. ์‚ฌ์šฉ์ž ์ •๋ณด ๋ฐ›๊ธฐ
    KakaoProfile userInfo = kaKaoApi.getUserInfo(accessToken);
    map.put("nickName", userInfo.getNickname());
    map.put("accessToken", accessToken);
    System.out.println("userInfo.getNickname() = " + userInfo.getNickname());
    System.out.println("accessToken = " + accessToken);
    
    return map;
}

-> ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธํ•œ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ๋™์ž‘ํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค. (๋กœ๊ทธ์ธ ํ›„ ๋‹ค๋ฅธ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜์ง€ ์•Š๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ทธ๋ƒฅ ์ •๋ณด๋ฅผ MAP์— ๋‹ด์•„ ๋ฆฌํ„ดํ•ด ๋งˆ๋ฌด๋ฆฌํ•œ๋‹ค.) 

 

์—ฌ๊ธฐ๊นŒ์ง€๊ฐ€ ์นด์นด์˜ค ๋กœ๊ทธ์ธ API๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ž‘์—…์ด๊ณ , ๊ทธ ๋’ค์— ๊ฐ์ž์˜ ์„œ๋น„์Šค์— ํšŒ์› ๊ฐ€์ž… ๋ฐ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ ์™„๋ฃŒ๋Š” ์ง์ ‘ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค! 

๋‚˜๋Š” ์šฐ์„  ์—ฌ๊ธฐ๊นŒ์ง€๋งŒ ๊ตฌํ˜„ํ•˜๊ณ , ๋‚˜์ค‘์— ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋” ๋ฐœ์ „์‹œ์ผœ๋ณผ ์˜ˆ์ •์ด๋‹ค.! 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90