Skip to main content

OAuth ์•ฑ ๊ถŒํ•œ ๋ถ€์—ฌ

๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๊ฐ€ OAuth app์— ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ  ํ•ญ๋ชฉ

GitHub App ๋Œ€์‹  OAuth app์„ ๋นŒ๋“œํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

OAuth apps ๋ฐ GitHub Apps ๋ชจ๋‘ OAuth 2.0์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

GitHub Apps์€(๋Š”) OAuth app๊ณผ(์™€) ์œ ์‚ฌํ•˜๊ฒŒ ์‚ฌ์šฉ์ž๋ฅผ ๋Œ€์‹ ํ•ด ์ž‘๋™ํ•˜๊ฑฐ๋‚˜, ์ž์ฒด์ ์œผ๋กœ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‚ฌ์šฉ์ž ์ž…๋ ฅ์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ์ž๋™ํ™”์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ GitHub Apps์€(๋Š”) ์„ธ๋ถ„ํ™”๋œ ์‚ฌ์šฉ ๊ถŒํ•œ์œผ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์•ฑ์ด ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ๋” ์ž˜ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ˆ˜๋ช…์ด ์งง์€ ํ† ํฐ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ GitHub ์•ฑ๊ณผ OAuth ์•ฑ ๊ฐ„์˜ ์ฐจ์ด์  ๋ฐ GitHub ์•ฑ ๋งŒ๋“ค๊ธฐ ์ •๋ณด์„(๋ฅผ) ์ฐธ์กฐํ•˜์„ธ์š”.

GitHub์˜ OAuth ๊ตฌํ˜„์€ ์›น ๋ธŒ๋ผ์šฐ์ €์— ์•ก์„ธ์Šคํ•  ์ˆ˜ ์—†๋Š” ์•ฑ์˜ ํ‘œ์ค€ ๊ถŒํ•œ ๋ถ€์—ฌ ์ฝ”๋“œ ๋ถ€์—ฌ ์œ ํ˜• ๋ฐ OAuth 2.0 ๋””๋ฐ”์ด์Šค ๊ถŒํ•œ ๋ถ€์—ฌ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

์•ฑ์„ ํ…Œ์ŠคํŠธํ•  ๋•Œ์™€ ๊ฐ™์ด ํ‘œ์ค€ ๋ฐฉ์‹์œผ๋กœ ์•ฑ์— ๋Œ€ํ•œ ๊ถŒํ•œ์„ ๊ฑด๋„ˆ๋›ฐ๋ ค๋ฉด ๋น„ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ๋ฆ„์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

OAuth app์— ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋ ค๋ฉด ์•ฑ์— ๊ฐ€์žฅ ์ ํ•ฉํ•œ ๊ถŒํ•œ ๋ถ€์—ฌ ํ๋ฆ„์„ ๊ณ ๋ คํ•˜์„ธ์š”.

์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ๋ฆ„

์ฐธ๊ณ  ํ•ญ๋ชฉ

GitHub ์•ฑ์„ ๋นŒ๋“œํ•˜๋Š” ๊ฒฝ์šฐ OAuth ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ๋ฆ„์„ ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์„ค์ •์—๋Š” ๋ช‡ ๊ฐ€์ง€ ์ค‘์š”ํ•œ ์ฐจ์ด์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์‚ฌ์šฉ์ž๋ฅผ ๋Œ€์‹ ํ•˜์—ฌ GitHub ์•ฑ์œผ๋กœ ์ธ์ฆ์„(๋ฅผ) ์ฐธ์กฐํ•˜์„ธ์š”.

์•ฑ ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š” ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ์‚ฌ์šฉ์ž๋Š” GitHub ID๋ฅผ ์š”์ฒญํ•˜๋„๋ก ๋ฆฌ๋””๋ ‰์…˜๋ฉ๋‹ˆ๋‹ค.
  2. GitHub๊ฐ€ ์‚ฌ์šฉ์ž๋ฅผ ์‚ฌ์ดํŠธ๋กœ ๋‹ค์‹œ ๋ฆฌ๋””๋ ‰์…˜ํ•ฉ๋‹ˆ๋‹ค.
  3. ์•ฑ์ด ์‚ฌ์šฉ์ž์˜ ์•ก์„ธ์Šค ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์—ฌ API์— ์•ก์„ธ์Šคํ•ฉ๋‹ˆ๋‹ค.

1. ์‚ฌ์šฉ์ž์˜ GitHub ID ์š”์ฒญ

GET https://github.com/login/oauth/authorize

์ด ๋์ ์€ ๋‹ค์Œ ์ž…๋ ฅ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ฟผ๋ฆฌ ๋งค๊ฐœ ๋ณ€์ˆ˜Typeํ•„์ˆ˜ ์—ฌ๋ถ€์„ค๋ช…
client_idstringํ•„์ˆ˜๋“ฑ๋ก ์‹œ GitHub์—์„œ ๋ฐ›์€ ํด๋ผ์ด์–ธํŠธ ID์ž…๋‹ˆ๋‹ค.
redirect_uristring๋งค์šฐ ๊ถŒ์žฅ๊ถŒํ•œ ๋ถ€์—ฌ ํ›„์— ์‚ฌ์šฉ์ž๋ฅผ ๋ณด๋‚ผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ URL์ž…๋‹ˆ๋‹ค. url ๋ฆฌ๋””๋ ‰์…˜์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.
loginstring์„ ํƒ ์‚ฌํ•ญ์•ฑ์— ๋กœ๊ทธ์ธํ•˜๊ณ  ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ํŠน์ • ๊ณ„์ •์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค.
scopestring์ปจํ…์ŠคํŠธ ์ข…์†๊ณต๋ฐฑ์œผ๋กœ ๊ตฌ๋ถ„๋˜๋Š” ๋ฒ”์œ„ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค. ์ œ๊ณต๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ scope๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฒ”์œ„์— ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜์ง€ ์•Š์€ ์‚ฌ์šฉ์ž์˜ ๋นˆ ๋ชฉ๋ก์œผ๋กœ ๊ธฐ๋ณธ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฒ”์œ„์— ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜์ง€ ์•Š์€ ์‚ฌ์šฉ์ž์˜ ๊ฒฝ์šฐ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ฒ”์œ„ ๋ชฉ๋ก์ด ํฌํ•จ๋œ OAuth ๊ถŒํ•œ ๋ถ€์—ฌ ํŽ˜์ด์ง€๊ฐ€ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ , ์ด ํ๋ฆ„ ๋‹จ๊ณ„๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•ด ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•œ ๋ฒ”์œ„ ์ง‘ํ•ฉ์œผ๋กœ ์ž๋™์œผ๋กœ ์™„๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฏธ ์›น ํ๋ฆ„์„ ๋‘ ๋ฒˆ ์ˆ˜ํ–‰ํ•˜๊ณ  user ๋ฒ”์œ„์˜ ํ† ํฐ ํ•˜๋‚˜์™€ repo ๋ฒ”์œ„์˜ ๋‹ค๋ฅธ ํ† ํฐ์— ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•œ ๊ฒฝ์šฐ, scope๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š” ์„ธ ๋ฒˆ์งธ ์›น ํ๋ฆ„์€ user ๋ฐ repo ๋ฒ”์œ„์˜ ํ† ํฐ์„ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค.
statestring๋งค์šฐ ๊ถŒ์žฅ์ถ”์ธกํ•  ์ˆ˜ ์—†๋Š” ์ž„์˜ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค. ๊ต์ฐจ ์‚ฌ์ดํŠธ ์š”์ฒญ ์œ„์กฐ ๊ณต๊ฒฉ์—์„œ ๋ณดํ˜ธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
code_challengestring๋งค์šฐ ๊ถŒ์žฅPKCE(์ฝ”๋“œ ๊ตํ™˜์šฉ ์ฆ๋ช… ํ‚ค)๋กœ ์ธ์ฆ ํ๋ฆ„์„ ๋ณดํ˜ธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. code_challenge_method๊ฐ€ ํฌํ•จ๋˜๋ฉด ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค. ํด๋ผ์ด์–ธํŠธ์—์„œ ์ƒ์„ฑ๋œ ์ž„์˜ ๋ฌธ์ž์—ด์˜ 43์ž SHA-256 ํ•ด์‹œ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ณด์•ˆ ํ™•์žฅ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ PKCE RFC๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.
code_challenge_methodstring๋งค์šฐ ๊ถŒ์žฅPKCE(์ฝ”๋“œ ๊ตํ™˜์šฉ ์ฆ๋ช… ํ‚ค)๋กœ ์ธ์ฆ ํ๋ฆ„์„ ๋ณดํ˜ธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. code_challenge๊ฐ€ ํฌํ•จ๋˜๋ฉด ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค. S256์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. plain ์ฝ”๋“œ ์ฑŒ๋ฆฐ์ง€ ๋ฉ”์„œ๋“œ๋Š” ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
allow_signupstring์„ ํƒ ์‚ฌํ•ญ์ธ์ฆ๋˜์ง€ ์•Š์€ ์‚ฌ์šฉ์ž์—๊ฒŒ OAuth ํ๋ฆ„ ์ค‘์— GitHub์— ๋“ฑ๋กํ•˜๋Š” ์˜ต์…˜์ด ์ œ๊ณต๋˜๋Š”์ง€ ์—ฌ๋ถ€์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ true์ž…๋‹ˆ๋‹ค. ์ •์ฑ…์—์„œ ๋“ฑ๋ก์„ ๊ธˆ์ง€ํ•  ๋•Œ false๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
promptstring์„ ํƒ ์‚ฌํ•ญselect_account๋กœ ์„ค์ •๋œ ๊ฒฝ์šฐ ๊ณ„์ • ์„ ํƒ๊ธฐ๋ฅผ ๊ฐ•์ œ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— HTTP๊ฐ€ ์•„๋‹Œ ๋ฆฌ๋””๋ ‰์…˜ URI๊ฐ€ ์žˆ๊ฑฐ๋‚˜ ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธํ•œ ๊ณ„์ •์ด ์—ฌ๋Ÿฌ ๊ฐœ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋„ ๊ณ„์ • ์„ ํƒ๊ธฐ๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ CORS pre-flight ์š”์ฒญ(OPTIONS)์€ ์ง€์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

2. GitHub๊ฐ€ ์‚ฌ์šฉ์ž๋ฅผ ์‚ฌ์ดํŠธ๋กœ ๋‹ค์‹œ ๋ฆฌ๋””๋ ‰์…˜

์‚ฌ์šฉ์ž๊ฐ€ ์š”์ฒญ์„ ์ˆ˜๋ฝํ•˜๋ฉด GitHub๋Š” state ๋งค๊ฐœ ๋ณ€์ˆ˜์˜ ์ด์ „ ๋‹จ๊ณ„์—์„œ ์ œ๊ณตํ•œ ์ƒํƒœ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ฝ”๋“œ ๋งค๊ฐœ ๋ณ€์ˆ˜์˜ ์ž„์‹œ code์™€ ํ•จ๊ป˜ ์‚ฌ์ดํŠธ๋กœ ๋‹ค์‹œ ๋ฆฌ๋””๋ ‰์…˜ํ•ฉ๋‹ˆ๋‹ค. ์ž„์‹œ ์ฝ”๋“œ๋Š” 10๋ถ„ ํ›„์— ๋งŒ๋ฃŒ๋ฉ๋‹ˆ๋‹ค. ์ƒํƒœ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด ํƒ€์‚ฌ์—์„œ ์š”์ฒญ์„ ๋งŒ๋“ค์—ˆ์œผ๋ฏ€๋กœ ํ”„๋กœ์„ธ์Šค๋ฅผ ์ค‘๋‹จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด code๋ฅผ ์•ก์„ธ์Šค ํ† ํฐ์œผ๋กœ ๊ตํ™˜ํ•ฉ๋‹ˆ๋‹ค.

POST https://github.com/login/oauth/access_token

์ด ๋์ ์€ ๋‹ค์Œ ์ž…๋ ฅ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜ ์ด๋ฆ„Typeํ•„์ˆ˜ ์—ฌ๋ถ€์„ค๋ช…
client_idstringํ•„์ˆ˜OAuth app์— ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด GitHub์—์„œ ๋ฐ›์€ ํด๋ผ์ด์–ธํŠธ ID์ž…๋‹ˆ๋‹ค.
client_secretstringRequiredOAuth app์— ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด GitHub์—์„œ ๋ฐ›์€ ํด๋ผ์ด์–ธํŠธ ์•”ํ˜ธ์ž…๋‹ˆ๋‹ค.
codestringRequired1๋‹จ๊ณ„์— ๋Œ€ํ•œ ์‘๋‹ต์œผ๋กœ ๋ฐ›์€ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.
redirect_uristring๋งค์šฐ ๊ถŒ์žฅ๊ถŒํ•œ ๋ถ€์—ฌ ํ›„ ์‚ฌ์šฉ์ž๊ฐ€ ์ „์†ก๋˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ URL์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ code๊ฐ€ ๋ฐœ๊ธ‰๋  ๋•Œ ์›๋ž˜ ์ œ๊ณต๋œ URI์™€ ๋Œ€์กฐํ•˜์—ฌ ์„œ๋น„์Šค์— ๋Œ€ํ•œ ๊ณต๊ฒฉ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
code_verifierstring๋งค์šฐ ๊ถŒ์žฅPKCE(์ฝ”๋“œ ๊ตํ™˜์šฉ ์ฆ๋ช… ํ‚ค)๋กœ ์ธ์ฆ ํ๋ฆ„์„ ๋ณดํ˜ธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ๊ถŒํ•œ ๋ถ€์—ฌ ์ค‘์— code_challenge๊ฐ€ ์ „์†ก๋œ ๊ฒฝ์šฐ ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค. ๊ถŒํ•œ ๋ถ€์—ฌ ์š”์ฒญ์—์„œ code_challenge๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ ์›๋ž˜ ๊ฐ’์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฐ’์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์•„ํ‚คํ…์ฒ˜์— ๋”ฐ๋ผ ์ธ์ฆ ์ค‘์— state ๋งค๊ฐœ ๋ณ€์ˆ˜์™€ ํ•จ๊ป˜ ์ฟ ํ‚ค์— ์ €์žฅ๋˜๊ฑฐ๋‚˜ ์„ธ์…˜ ๋ณ€์ˆ˜์— ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ์‘๋‹ต์˜ ํ˜•์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

access_token=gho_16C7e42F292c6912E7710c838347Ae178B4a&scope=repo%2Cgist&token_type=bearer

Accept ํ—ค๋”์— ํ˜•์‹์„ ์ œ๊ณตํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค๋ฅธ ํ˜•์‹์œผ๋กœ ์‘๋‹ต์„ ๋ฐ›์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Accept: application/json ๋˜๋Š” Accept: application/xml์ž…๋‹ˆ๋‹ค.

Accept: application/json
{
  "access_token":"gho_16C7e42F292c6912E7710c838347Ae178B4a",
  "scope":"repo,gist",
  "token_type":"bearer"
}
Accept: application/xml
<OAuth>
  <token_type>bearer</token_type>
  <scope>repo,gist</scope>
  <access_token>gho_16C7e42F292c6912E7710c838347Ae178B4a</access_token>
</OAuth>

3. ์•ก์„ธ์Šค ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์—ฌ API์— ์•ก์„ธ์Šค

์•ก์„ธ์Šค ํ† ํฐ์„ ์‚ฌ์šฉํ•˜๋ฉด ์‚ฌ์šฉ์ž๋ฅผ ๋Œ€์‹ ํ•˜์—ฌ API์— ์š”์ฒญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Authorization: Bearer OAUTH-TOKEN
GET https://api.github.com/user

์˜ˆ๋ฅผ ๋“ค์–ด curl์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ธ์ฆ ํ—ค๋”๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

curl -H "Authorization: Bearer OAUTH-TOKEN" https://api.github.com/user

์•ก์„ธ์Šค ํ† ํฐ์„ ๋ฐ›์„ ๋•Œ๋งˆ๋‹ค ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž์˜ ID ์œ ํšจ์„ฑ์„ ๋‹ค์‹œ ๊ฒ€์‚ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๋Š” ์•ฑ์— ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๊ธฐ ์œ„ํ•ด ๋กœ๊ทธ์ธํ•  ๋•Œ ๋กœ๊ทธ์ธํ•œ ๊ณ„์ •์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋กœ๊ทธ์ธํ•  ๋•Œ๋งˆ๋‹ค ์‚ฌ์šฉ์ž ID์˜ ์œ ํšจ์„ฑ์„ ๊ฒ€์‚ฌํ•˜์ง€ ์•Š์œผ๋ฉด ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๊ฐ€ ํ˜ผ์šฉ๋  ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋””๋ฐ”์ด์Šค ํ๋ฆ„

๋””๋ฐ”์ด์Šค ํ๋ฆ„์„ ์‚ฌ์šฉํ•˜๋ฉด CLI ๋„๊ตฌ ๋˜๋Š” Git ์ž๊ฒฉ ์ฆ๋ช… ๊ด€๋ฆฌ์ž์™€ ๊ฐ™์€ ํ—ค๋“œ๋ฆฌ์Šค ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋””๋ฐ”์ด์Šค ํ๋ฆ„์„ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉ์ž์—๊ฒŒ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๊ณ  ์‹๋ณ„ํ•˜๋ ค๋ฉด ๋จผ์ € ์•ฑ ์„ค์ •์—์„œ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•ฑ์—์„œ ๋””๋ฐ”์ด์Šค ํ๋ฆ„์„ ํ™œ์„ฑํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€GitHub Apps์— ๋Œ€ํ•œ GitHub ์•ฑ ๋“ฑ๋ก ์ˆ˜์ • ๋ฐ OAuth apps์— ๋Œ€ํ•œ OAuth ์•ฑ ์ˆ˜์ •์„(๋ฅผ) ์ฐธ์กฐํ•˜์„ธ์š”.

๋””๋ฐ”์ด์Šค ํ๋ฆ„ ๊ฐœ์š”

  1. ์•ฑ์€ ๋””๋ฐ”์ด์Šค ๋ฐ ์‚ฌ์šฉ์ž ํ™•์ธ ์ฝ”๋“œ๋ฅผ ์š”์ฒญํ•˜๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉ์ž ํ™•์ธ ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•  ๊ถŒํ•œ ๋ถ€์—ฌ URL์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
  2. ์•ฑ์€ ์‚ฌ์šฉ์ž์—๊ฒŒ https://github.com/login/device์— ์‚ฌ์šฉ์ž ํ™•์ธ ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•˜๋ผ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  3. ์•ฑ์€ ์‚ฌ์šฉ์ž ์ธ์ฆ ์ƒํƒœ๋ฅผ ํด๋งํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋””๋ฐ”์ด์Šค์— ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋ฉด ์•ฑ์€ ์ƒˆ ์•ก์„ธ์Šค ํ† ํฐ์œผ๋กœ API ํ˜ธ์ถœ์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1๋‹จ๊ณ„: ์•ฑ์ด GitHub์—์„œ ๋””๋ฐ”์ด์Šค ๋ฐ ์‚ฌ์šฉ์ž ํ™•์ธ ์ฝ”๋“œ๋ฅผ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.

POST https://github.com/login/device/code

์•ฑ์€ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋‹ค์Œ ๋‹จ๊ณ„์—์„œ ์ธ์ฆํ•˜๋ผ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์‚ฌ์šฉ์ž ํ™•์ธ ์ฝ”๋“œ ๋ฐ ํ™•์ธ URL์„ ์š”์ฒญํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ์ด ์š”์ฒญ์€ ์•ฑ์ด ์•ก์„ธ์Šค ํ† ํฐ์„ ์ˆ˜์‹ ํ•˜๊ณ  ์‚ฌ์šฉ์ž ์ธ์ฆ ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๋””๋ฐ”์ด์Šค ํ™•์ธ ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๋์ ์€ ๋‹ค์Œ ์ž…๋ ฅ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜ ์ด๋ฆ„Type์„ค๋ช…
client_idstringํ•„์ˆ˜์ž…๋‹ˆ๋‹ค. ์•ฑ์— ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด GitHub์—์„œ ๋ฐ›์€ ํด๋ผ์ด์–ธํŠธ ID์ž…๋‹ˆ๋‹ค.
scopestring์•ฑ์ด ์•ก์„ธ์Šค๋ฅผ ์š”์ฒญํ•˜๋Š” ๋ฒ”์œ„์˜ ๊ณต๋ฐฑ์œผ๋กœ ๊ตฌ๋ถ„๋œ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ OAuth ์•ฑ์— ๋Œ€ํ•œ ๋ฒ”์œ„์„(๋ฅผ) ์ฐธ์กฐํ•˜์„ธ์š”.

๊ธฐ๋ณธ์ ์œผ๋กœ ์‘๋‹ต์˜ ํ˜•์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

device_code=3584d83530557fdd1f46af8289938c8ef79f9dc5&expires_in=900&interval=5&user_code=WDJB-MJHT&verification_uri=https%3A%2F%2Fgithub.com%2Flogin%2Fdevice
๋งค๊ฐœ ๋ณ€์ˆ˜ ์ด๋ฆ„Type์„ค๋ช…
device_codestring๋””๋ฐ”์ด์Šค ํ™•์ธ ์ฝ”๋“œ๋Š” 40์ž์ด๋ฉฐ ๋””๋ฐ”์ด์Šค๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
user_codestring์‚ฌ์šฉ์ž๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋„๋ก ์‚ฌ์šฉ์ž ํ™•์ธ ์ฝ”๋“œ๊ฐ€ ๋””๋ฐ”์ด์Šค์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์ด ์ฝ”๋“œ๋Š” 8์ž์ด๋ฉฐ ์ค‘๊ฐ„์— ํ•˜์ดํ”ˆ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
verification_uristring์‚ฌ์šฉ์ž๊ฐ€ user_code๋ฅผ ์ž…๋ ฅํ•ด์•ผ ํ•˜๋Š” ํ™•์ธ URL( https://github.com/login/device)์ž…๋‹ˆ๋‹ค.
expires_inintegerdevice_code ๋ฐ user_code์˜ ๋งŒ๋ฃŒ ์ „ ์‹œ๊ฐ„(์ดˆ)์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ 900์ดˆ(๋˜๋Š” 15๋ถ„)์ž…๋‹ˆ๋‹ค.
intervalinteger๋””๋ฐ”์ด์Šค ๊ถŒํ•œ ๋ถ€์—ฌ๋ฅผ ์™„๋ฃŒํ•˜๋ ค๋ฉด ์ƒˆ ์•ก์„ธ์Šค ํ† ํฐ์„ ์š”์ฒญํ•˜๊ธฐ ์ „์— ๊ฒฝ๊ณผํ•ด์•ผ ํ•˜๋Š” ์ตœ์†Œ ์‹œ๊ฐ„(์ดˆ)์ž…๋‹ˆ๋‹ค(POST https://github.com/login/oauth/access_token). ์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐ„๊ฒฉ์ด 5์ด๋ฉด 5์ดˆ๊ฐ€ ์ง€๋‚˜์•ผ ์ƒˆ๋กœ ์š”์ฒญํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 5์ดˆ ๋™์•ˆ ๋‘ ๋ฒˆ ์ด์ƒ ์š”์ฒญํ•˜๋ฉด ์†๋„ ์ œํ•œ์— ๋„๋‹ฌํ•˜๋ฉด์„œ slow_down ์˜ค๋ฅ˜๋ฅผ ์ˆ˜์‹ ํ•ฉ๋‹ˆ๋‹ค.

Accept ํ—ค๋”์— ํ˜•์‹์„ ์ œ๊ณตํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค๋ฅธ ํ˜•์‹์œผ๋กœ ์‘๋‹ต์„ ๋ฐ›์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Accept: application/json ๋˜๋Š” Accept: application/xml์ž…๋‹ˆ๋‹ค.

Accept: application/json
{
  "device_code": "3584d83530557fdd1f46af8289938c8ef79f9dc5",
  "user_code": "WDJB-MJHT",
  "verification_uri": "https://github.com/login/device",
  "expires_in": 900,
  "interval": 5
}
Accept: application/xml
<OAuth>
  <device_code>3584d83530557fdd1f46af8289938c8ef79f9dc5</device_code>
  <user_code>WDJB-MJHT</user_code>
  <verification_uri>https://github.com/login/device</verification_uri>
  <expires_in>900</expires_in>
  <interval>5</interval>
</OAuth>

2๋‹จ๊ณ„: ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์‚ฌ์šฉ์ž ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•˜๋ผ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

๋””๋ฐ”์ด์Šค์— ์‚ฌ์šฉ์ž ํ™•์ธ ์ฝ”๋“œ๊ฐ€ ํ‘œ์‹œ๋˜๊ณ  https://github.com/login/device์— ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•˜๋ผ๋Š” ๋ฉ”์‹œ์ง€๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

3๋‹จ๊ณ„: ์•ฑ์ด GitHub๋ฅผ ํด๋งํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋””๋ฐ”์ด์Šค์— ๊ถŒํ•œ์„ ๋ถ€์—ฌํ–ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

POST https://github.com/login/oauth/access_token

๋””๋ฐ”์ด์Šค ๋ฐ ์‚ฌ์šฉ์ž ์ฝ”๋“œ๊ฐ€ ๋งŒ๋ฃŒ๋˜๊ฑฐ๋‚˜ ์‚ฌ์šฉ์ž๊ฐ€ ์œ ํšจํ•œ ์‚ฌ์šฉ์ž ์ฝ”๋“œ๋กœ ์•ฑ์— ๊ถŒํ•œ์„ ์„ฑ๊ณต์ ์œผ๋กœ ๋ถ€์—ฌํ•  ๋•Œ๊นŒ์ง€ ์•ฑ์€ POST https://github.com/login/oauth/access_token์„ ํด๋งํ•˜๋Š” ๋””๋ฐ”์ด์Šค ๊ถŒํ•œ ๋ถ€์—ฌ ์š”์ฒญ์„ ํ•ฉ๋‹ˆ๋‹ค. ์•ฑ์ด ์†๋„ ์ œํ•œ ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๋ ค๋ฉด 1๋‹จ๊ณ„์—์„œ ๊ฒ€์ƒ‰๋œ ์ตœ์†Œ ํด๋ง interval์„ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋””๋ฐ”์ด์Šค ํ๋ฆ„์— ๋Œ€ํ•œ ์†๋„ ์ œํ•œ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

์‚ฌ์šฉ์ž๋Š” 15๋ถ„(๋˜๋Š” 900์ดˆ) ์ด๋‚ด์— ์œ ํšจํ•œ ์ฝ”๋“œ๋ฅผ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 15๋ถ„์ด ์ง€๋‚˜๋ฉด POST https://github.com/login/device/code๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ ๋””๋ฐ”์ด์Šค ๊ถŒํ•œ ๋ถ€์—ฌ ์ฝ”๋“œ๋ฅผ ์š”์ฒญํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž๊ฐ€ ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•˜๋ฉด ์•ฑ์€ ์‚ฌ์šฉ์ž๋ฅผ ๋Œ€์‹ ํ•˜์—ฌ API์— ์š”์ฒญํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์•ก์„ธ์Šค ํ† ํฐ์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋์ ์€ ๋‹ค์Œ ์ž…๋ ฅ ๋งค๊ฐœ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋งค๊ฐœ ๋ณ€์ˆ˜ ์ด๋ฆ„Type์„ค๋ช…
client_idstringํ•„์ˆ˜์ž…๋‹ˆ๋‹ค. OAuth app์— ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด GitHub์—์„œ ๋ฐ›์€ ํด๋ผ์ด์–ธํŠธ ID์ž…๋‹ˆ๋‹ค.
device_codestringํ•„์ˆ˜์ž…๋‹ˆ๋‹ค. POST https://github.com/login/device/code ์š”์ฒญ์—์„œ ๋ฐ›์€ device_code์ž…๋‹ˆ๋‹ค.
grant_typestringํ•„์ˆ˜์ž…๋‹ˆ๋‹ค. ๊ถŒํ•œ ๋ถ€์—ฌ ์œ ํ˜•์€ urn:ietf:params:oauth:grant-type:device_code์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ์‘๋‹ต์˜ ํ˜•์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

access_token=gho_16C7e42F292c6912E7710c838347Ae178B4a&token_type=bearer&scope=repo%2Cgist

Accept ํ—ค๋”์— ํ˜•์‹์„ ์ œ๊ณตํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค๋ฅธ ํ˜•์‹์œผ๋กœ ์‘๋‹ต์„ ๋ฐ›์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Accept: application/json ๋˜๋Š” Accept: application/xml์ž…๋‹ˆ๋‹ค.

Accept: application/json
{
 "access_token": "gho_16C7e42F292c6912E7710c838347Ae178B4a",
  "token_type": "bearer",
  "scope": "repo,gist"
}
Accept: application/xml
<OAuth>
  <access_token>gho_16C7e42F292c6912E7710c838347Ae178B4a</access_token>
  <token_type>bearer</token_type>
  <scope>gist,repo</scope>
</OAuth>

๋””๋ฐ”์ด์Šค ํ๋ฆ„์˜ ์†๋„ ์ œํ•œ

์‚ฌ์šฉ์ž๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์—์„œ ํ™•์ธ ์ฝ”๋“œ๋ฅผ ์ œ์ถœํ•˜๋Š” ๊ฒฝ์šฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋‹น 1์‹œ๊ฐ„์— 50๊ฐœ์˜ ์ œ์ถœ ์†๋„ ์ œํ•œ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์š”์ฒญ ๊ฐ„์— ํ•„์š”ํ•œ ์ตœ์†Œ ๊ธฐ๊ฐ„ ๋‚ด(๋˜๋Š” interval)์— ๋‘˜ ์ด์ƒ์˜ ์•ก์„ธ์Šค ํ† ํฐ ์š”์ฒญ(POST https://github.com/login/oauth/access_token)์„ ํ•˜๋Š” ๊ฒฝ์šฐ ์†๋„ ์ œํ•œ์— ๋„๋‹ฌํ•˜๊ณ  slow_down ์˜ค๋ฅ˜ ์‘๋‹ต์„ ์ˆ˜์‹ ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. slow_down ์˜ค๋ฅ˜ ์‘๋‹ต์€ ๋งˆ์ง€๋ง‰ interval์— 5์ดˆ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋””๋ฐ”์ด์Šค ํ๋ฆ„์˜ ์˜ค๋ฅ˜ ์ฝ”๋“œ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๋””๋ฐ”์ด์Šค ํ๋ฆ„์˜ ์˜ค๋ฅ˜ ์ฝ”๋“œ

์˜ค๋ฅ˜ ์ฝ”๋“œ์„ค๋ช…
authorization_pending์ด ์˜ค๋ฅ˜๋Š” ๊ถŒํ•œ ๋ถ€์—ฌ ์š”์ฒญ์ด ๋ณด๋ฅ˜ ์ค‘์ด๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉ์ž ์ฝ”๋“œ๋ฅผ ์•„์ง ์ž…๋ ฅํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์— ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ์•ฑ์€ ๊ฐ ์š”์ฒญ ์‚ฌ์ด์— ์ตœ์†Œ ์‹œ๊ฐ„(์ดˆ)์ด ํ•„์š”ํ•œ interval์„ ์ดˆ๊ณผํ•˜์ง€ ์•Š๊ณ  POST https://github.com/login/oauth/access_token ์š”์ฒญ์„ ๊ณ„์† ํด๋งํ•  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋ฉ๋‹ˆ๋‹ค.
slow_downslow_down ์˜ค๋ฅ˜๋ฅผ ์ˆ˜์‹ ํ•˜๋Š” ๊ฒฝ์šฐ POST https://github.com/login/oauth/access_token์„ ์‚ฌ์šฉํ•˜์—ฌ ์š”์ฒญ ๊ฐ„ ํ•„์š”ํ•œ ์ตœ์†Œ interval ๋˜๋Š” ๊ธฐ๊ฐ„์— 5์ดˆ๊ฐ€ ๋” ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์‹œ์ž‘ ๊ฐ„๊ฒฉ์ด ์š”์ฒญ ์‚ฌ์ด์— 5์ดˆ ์ด์ƒ ํ•„์š”ํ•˜๊ณ  slow_down ์˜ค๋ฅ˜ ์‘๋‹ต์„ ์ˆ˜์‹ ํ•˜๋Š” ๊ฒฝ์šฐ OAuth ์•ก์„ธ์Šค ํ† ํฐ์„ ์ƒˆ๋กœ ์š”์ฒญํ•˜๊ธฐ ์ „์— ์ตœ์†Œ 10์ดˆ ๋™์•ˆ ๊ธฐ๋‹ค๋ ค์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์˜ค๋ฅ˜ ์‘๋‹ต์—๋Š” ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ์ƒˆ interval์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
expired_token๋””๋ฐ”์ด์Šค ์ฝ”๋“œ๊ฐ€ ๋งŒ๋ฃŒ๋˜๋ฉด token_expired ์˜ค๋ฅ˜๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ ๋””๋ฐ”์ด์Šค ์ฝ”๋“œ๋ฅผ ์ƒˆ๋กœ ์š”์ฒญํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
unsupported_grant_typeOAuth ํ† ํฐ ์š”์ฒญ POST https://github.com/login/oauth/access_token์„ ํด๋งํ•  ๋•Œ ๊ถŒํ•œ ๋ถ€์—ฌ ํ˜•์‹์€ urn:ietf:params:oauth:grant-type:device_code์ด๋ฉฐ ์ž…๋ ฅ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ํฌํ•จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
incorrect_client_credentials๋””๋ฐ”์ด์Šค ํ๋ฆ„์˜ ๊ฒฝ์šฐ ์•ฑ ์„ค์ • ํŽ˜์ด์ง€์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ๋Š” ์•ฑ์˜ ํด๋ผ์ด์–ธํŠธ ID๋ฅผ ์ „๋‹ฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. client_secret์€ ๋””๋ฐ”์ด์Šค ํ๋ฆ„์— ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
incorrect_device_code์ œ๊ณต๋œ device_code๋Š” ์ž˜๋ชป๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
access_denied๊ถŒํ•œ ๋ถ€์—ฌ ํ”„๋กœ์„ธ์Šค ์ค‘์— ์‚ฌ์šฉ์ž๊ฐ€ ์ทจ์†Œ๋ฅผ ํด๋ฆญํ•˜๋ฉด access_denied ์˜ค๋ฅ˜๋ฅผ ์ˆ˜์‹ ํ•˜๊ฒŒ ๋˜๊ณ  ์‚ฌ์šฉ์ž๋Š” ํ™•์ธ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
device_flow_disabled์•ฑ ์„ค์ •์—์„œ ๋””๋ฐ”์ด์Šค ํ๋ฆ„์„ ์‚ฌ์šฉํ•˜๋„๋ก ์„ค์ •ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋””๋ฐ”์ด์Šค ํ๋ฆ„์„ ์ฐธ์กฐํ•˜์„ธ์š”.

์ž์„ธํ•œ ๋‚ด์šฉ์€ OAuth 2.0 ๋””๋ฐ”์ด์Šค ๊ถŒํ•œ ๋ถ€์—ฌ๋ฅผ ์ฐธ์กฐํ•˜์„ธ์š”.

๋น„ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ๋ฆ„

๋น„ ์›น ์ธ์ฆ์€ ํ…Œ์ŠคํŠธ์™€ ๊ฐ™์€ ์ œํ•œ๋œ ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๊ธฐ๋ณธ ์ธ์ฆ์„ ์‚ฌ์šฉํ•˜์—ฌ personal access token์˜ ์„ค์ • ํŽ˜์ด์ง€๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ personal access token์„(๋ฅผ) ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์œผ๋กœ ์‚ฌ์šฉ์ž๋Š” ์–ธ์ œ๋“ ์ง€ ์•ก์„ธ์Šค๋ฅผ ์ฒ ํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฆฌ๋””๋ ‰์…˜ URL

redirect_uri ๋งค๊ฐœ ๋ณ€์ˆ˜๋Š” ์„ ํƒ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์ œ์™ธ๋˜๋Š” ๊ฒฝ์šฐ GitHub๋Š” OAuth app ์„ค์ •์— ๊ตฌ์„ฑ๋œ ์ฝœ๋ฐฑ URL๋กœ ์‚ฌ์šฉ์ž๋ฅผ ๋ฆฌ๋””๋ ‰์…˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ์ œ๊ณต๋˜๋Š” ๊ฒฝ์šฐ ๋ฆฌ๋””๋ ‰์…˜ URL์˜ ํ˜ธ์ŠคํŠธ(์„œ๋ธŒ ๋„๋ฉ”์ธ ์ œ์™ธ) ๋ฐ ํฌํŠธ๊ฐ€ ์ฝœ๋ฐฑ URL๊ณผ ์ •ํ™•ํžˆ ์ผ์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋ฆฌ๋””๋ ‰์…˜ URL์˜ ๊ฒฝ๋กœ๋Š” ์ฝœ๋ฐฑ URL์˜ ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ์ฐธ์กฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

CALLBACK: http://example.com/path

GOOD: http://example.com/path
GOOD: http://example.com/path/subdir/other
GOOD: http://oauth.example.com/path
GOOD: http://oauth.example.com/path/subdir/other
BAD:  http://example.com/bar
BAD:  http://example.com/
BAD:  http://example.com:8080/path
BAD:  http://oauth.example.com:8080/path
BAD:  http://example.org

๋ฃจํ”„๋ฐฑ ๋ฆฌ๋””๋ ‰์…˜ URL

์„ ํƒ์  redirect_uri ๋งค๊ฐœ ๋ณ€์ˆ˜๋Š” ๋ฐ์Šคํฌํ†ฑ ์ปดํ“จํ„ฐ์—์„œ ์‹คํ–‰๋˜๋Š” ์›์‹œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์œ ์šฉํ•œ ๋ฃจํ”„๋ฐฑ URL์—๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฃจํ”„๋ฐฑ URL ๋ฐ ํฌํŠธ๋ฅผ ์ง€์ •ํ•˜๋Š” ๊ฒฝ์šฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•œ ํ›„ ์‚ฌ์šฉ์ž๋Š” ์ œ๊ณต๋œ URL ๋ฐ ํฌํŠธ๋กœ ๋ฆฌ๋””๋ ‰์…˜๋ฉ๋‹ˆ๋‹ค. redirect_uri์€ ์•ฑ์˜ ์ฝœ๋ฐฑ URL์— ์ง€์ •๋œ ํฌํŠธ์™€ ์ผ์น˜ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

http://127.0.0.1/path ์ฝœ๋ฐฑ URL์˜ ๊ฒฝ์šฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด 1234 ํฌํŠธ์—์„œ ์ˆ˜์‹  ๋Œ€๊ธฐ ์ค‘์ด๋ฉด ํ•ด๋‹น redirect_uri์„(๋ฅผ) ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

http://127.0.0.1:1234/path

OAuth RFC๋Š” ๋ฃจํ”„๋ฐฑ ๋ฆฌํ„ฐ๋Ÿด 127.0.0.1 ๋˜๋Š” IPv6 ::1์„ ์‚ฌ์šฉํ•˜๊ณ  localhost๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

OAuth apps์šฉ์œผ๋กœ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ† ํฐ ๋งŒ๋“ค๊ธฐ

์‚ฌ์šฉ์ž/์• ํ”Œ๋ฆฌ์ผ€์ด์…˜/๋ฒ”์œ„ ์กฐํ•ฉ์— ์—ฌ๋Ÿฌ ํ† ํฐ์„ ๋งŒ๋“ค์–ด ํŠน์ • ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์œ„ํ•œ ํ† ํฐ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Š” OAuth app์ด(๊ฐ€) ๋กœ๊ทธ์ธ์— GitHub๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๊ธฐ๋ณธ ์‚ฌ์šฉ์ž ์ •๋ณด๋งŒ ํ•„์š”ํ•œ ๋‹จ์ผ ์›Œํฌํ”Œ๋กœ๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์›Œํฌํ”Œ๋กœ์—์„œ๋Š” ์‚ฌ์šฉ์ž์˜ ํ”„๋ผ์ด๋น— ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ์•ก์„ธ์Šคํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. OAuth app์€(๋Š”) ์—ฌ๋Ÿฌ ํ† ํฐ์„ ์‚ฌ์šฉํ•ด ํ•„์š”ํ•œ ๋ฒ”์œ„๋งŒ ์š”์ฒญํ•˜์—ฌ ์‚ฌ์šฉ ์‚ฌ๋ก€๋งˆ๋‹ค ์›น ํ๋ฆ„์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋กœ๊ทธ์ธํ•˜๋Š” ๊ฒฝ์šฐ OAuth app์— ํ”„๋ผ์ด๋น— ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ๋Œ€ํ•œ ์•ก์„ธ์Šค ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

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

๊ฒฝ๊ณ 

OAuth app์—์„œ ๋ชจ๋“  ๊ถŒํ•œ์„ ์ทจ์†Œํ•˜๋ฉด ๋ฐฐํฌ ํ‚ค๋ฅผ ํฌํ•จํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‚ฌ์šฉ์ž๋ฅผ ๋Œ€์‹ ํ•˜์—ฌ ์ƒ์„ฑํ•œ ๋ชจ๋“  SSH ํ‚ค๊ฐ€ ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž์—๊ฒŒ ์•ก์„ธ์Šค ๊ถŒํ•œ์„ ๊ฒ€ํ† ํ•˜๋„๋ก ์ง€์‹œ

OAuth app์— ๋Œ€ํ•œ ๊ถŒํ•œ ๋ถ€์—ฌ ์ •๋ณด์— ์—ฐ๊ฒฐํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ถŒํ•œ ๋ถ€์—ฌ๋ฅผ ๊ฒ€ํ† ํ•˜๊ณ  ์ฒ ํšŒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—ฐ๊ฒฐ ๋งํฌ๋ฅผ ๋นŒ๋“œํ•˜๋ ค๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋“ฑ๋กํ•  ๋•Œ GitHub์—์„œ ๋ฐ›์€ OAuth app client_id๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

https://github.com/settings/connections/applications/:client_id

ํŒ

OAuth app์ด ์‚ฌ์šฉ์ž์— ๋Œ€ํ•ด ์•ก์„ธ์Šคํ•  ์ˆ˜ ์žˆ๋Š” ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ๋ฆฌ์†Œ์Šค ๊ฒ€์ƒ‰์„(๋ฅผ) ์ฐธ์กฐํ•˜์„ธ์š”.

๋ฌธ์ œ ํ•ด๊ฒฐ

์ถ”๊ฐ€ ์ฐธ๊ณ  ์ž๋ฃŒ