๐ก๏ธOAuth
์ ์

์ฌ์ฉ์๋ค์ด ์ 3์ ์๋น์ค์ ๊ณ์ ์ ํตํด ์ธ์ฆ์ ์ํํ ์ ์๋๋ก ์ ๊ทผ ์์์ ์ ๊ณตํ๋ ๊ณตํต ํ์ค(open standard) ์ธ์ฆ๋ฐฉ์
์ฌ๊ธฐ์ ์ 3์ ์๋น์ค๋ Google, Facebook, Github ๋ฑ์ ํฌํจํ๋ค.
์ฅ์ (๋ฌธ์ ํด๊ฒฐ)
๊ธฐ์กด์๋ ์ 3์ ์๋น์ค์ ๊ณ์ ์ ์ด์ฉํ๊ธฐ ์ํด ๋ณธ ์๋น์ค์ ์ 3์ ์๋น์ค์ ๋ชจ๋ ์ฌ์ฉ์์ ์์ด๋/๋น๋ฐ๋ฒํธ๋ฅผ ์ ๊ณตํด์ผ ํจ โ ๋ณด์ ์ธก๋ฉด์์ ์ํด (ํ๋ ํธ๋ฆฌ๋ฉด ๋ค ํธ๋ฆผ!)
OAuth๋ฅผ ์ด์ฉํ๋ฉด ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ์ฌ์ฉ์์ ๊ฐ์ธ ์ ๋ณด๊ฐ ์๋ ์์๋ก ์์ฑ๋๋ ๊ฐ์ธ
accessToken์ ์ด์ฉํด ์ธ์ฆ์ ์ํํ๊ธฐ ๋๋ฌธ์, ๋ ๊ฐ ์๋น์ค ๋ชจ๋์ ๊ฐ์ธ ์ ๋ณด๋ฅผ ์ ๊ณตํ ํ์๊ฐ ์๋ค.
์ 3์ ์๋น์ค์ ์์ด๋/๋น๋ฐ๋ฒํธ๋ฅผ ์ ๊ณตํ๋ ํ์์์๋ ๋ณธ ์๋น์ค๊ฐ ์ด๋ฅผ ๋จ์ฉํ ์ฐ๋ ค๊ฐ ์์๋ค.
OAuth๋ฅผ ์ด์ฉํ๋ฉด ํ์ฉํ ๊ถํ์ ์ ํํ ์ ์๊ณ , ์ฌ์ฉ์๊ฐ ์ธ์ฆ ๊ณผ์ ์์ ์ด ๊ถํ์ด ๋ฌด์์ธ์ง ํ์ธํ ์ ์๋ค.
์ฉ์ด
Resource Owner- ์ฌ์ฉ์. Resource(๊ฐ์ธ ์ ๋ณด)์ ์์ ์Resource Server- ์ 3์ ์๋น์ค. Resource(๊ฐ์ธ ์ ๋ณด)๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ, ์ ๊ณตํ๋ ์ฃผ์ฒดAuthorization Server- OAuth๋ฅผ ์ ๊ณตํ๋ ์ 3์ ์๋น์ค์ ์ํ, ์ธ์ฆ ๊ด๋ จ ์ฒ๋ฆฌ๋ฅผ ๋ด๋นํ๋ ์๋ฒ
Client- ์ด์ฉํ๋ ค๋ ์๋น์ค. Resource Server์ ์ ๊ทผํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ป๊ณ ํ์ฉํ๋ ์ฃผ์ฒด
์ธ์ฆ ํ๋ฆ
OAuth ์ธ์ฆ์ ํตํ ๋ก๊ทธ์ธ์ ์ ๊ณตํ๋ Client ์ ์ฅ์์์ ์ธ์ฆ ํ๋ฆ์ ๋ค์๊ณผ ๊ฐ๋ค.
OAuth ์ธ์ฆ ๋ฐฉ์์ ์ ๊ณตํ๊ธฐ ์ํด ์ธ์ฆ ์๋ฒ๋ฅผ ์ ๊ณตํ๋ ๋ฆฌ์์ค ์๋ฒ์ ๋ด ์๋น์ค๋ฅผ ๋ฑ๋กํ๋ค.
๋ฆฌ์์ค ์๋ฒ๋ ์ฐจํ ๋ฑ๋ก๋ ์๋น์ค์ ์ธ์ฆ์ ์ํด
Client ID,Client Secret์ ๋ฐ๊ธํ๋ค.์ฌ์ฉ์๊ฐ OAuth ๋ก๊ทธ์ธ(๊ตฌ๊ธ๋ก ๋ก๊ทธ์ธ, ์นด์นด์ค๋ก ๋ก๊ทธ์ธ ๋ฑ)์ ์์ฒญํ๋ค.
๋ด ์๋ฒ๋ ์ด๋ฅผ ๋ฐ์ ์ฌ์ฉ์๋ฅผ ์ธ์ฆ ์๋ฒ๊ฐ ์ ๊ณตํ๋ ์ธ์ฆ ํ์ด์ง๋ก ์ด๋์ํจ๋ค. ์ด ๋ ์ธ์ฆ ์๋ฒ์๋ ํด๋ผ์ด์ธํธ ์์ด๋, ๊ถํ์ ๋ถ์ฌ๋ฐ์ ์์ญ(scope), ์ธ์ฆ ํ ๋ฆฌ๋ค์ด๋ ํธํ URL์ด GET ์์ฒญ์ ํ๋ผ๋ฏธํฐ๋ก ์ ๊ณต๋์ด์ผ ํ๋ค.
https://resource.server?client_id={ํด๋ผ์ด์ธํธ์์ด๋}&scope=email,profile...&redirect_url=https://client/callback์ฌ์ฉ์๊ฐ ์ธ์ฆ์ ์ํ(๋์)ํ๋ฉด ๋ฆฌ์์ค ์๋ฒ๋ code๋ฅผ ๋ฐ๊ธํ๋ค. code๋ ์ง์ ์ ์ ๊ณตํ ๋ฆฌ๋ค์ด๋ ํธ URL๋ก ์ฌ์ฉ์๋ฅผ ๋ฆฌ๋ค์ด๋ ํธ์ํค๋ฉฐ ์ ๊ณต๋๋ค.
https://client/callback?code={์ฝ๋}๋ด ์๋ฒ๋ ์ด๋ฅผ ๋ฐ์ ์ธ์ฆ ์๋ฒ์ access token์ ๋ฐ๊ธํ ๊ฒ์ ์์ฒญํ๋ค. ์ด ๋ ์ธ์ฆ ์๋ฒ์๋ Client ID, Client Secret, ์ง์ ์ ๋ฐ๊ธํ code, ๋ฆฌ๋ค์ด๋ ํธํ URL์ด POST ์์ฒญ์ ํ๋ผ๋ฏธํฐ๋ก ์ ๊ณต๋์ด์ผ ํ๋ค.
https://resource.server/token?code={์ฝ๋}&client_id={ํด๋ผ์ด์ธํธ์์ด๋}&client_secret={ํด๋ผ์ด์ธํธ์ํฌ๋ฆฟ}&redirect_url=https://client/callback๋ฆฌ์์ค ์๋ฒ๋ ํด๋ผ์ด์ธํธ ์์ด๋์ ์ํฌ๋ฆฟ, ์ฝ๋๊ฐ ๋ชจ๋ ์ผ์นํ๋์ง ํ์ธํ๊ณ ๋ง๋ค๋ฉด access token์ ๋ฐ๊ธํ์ฌ ์ด๋ฅผ ํฌํจํ JSON์ ๋ฐํํ๋ค.
{ "access_token": "์ก์ธ์ค ํ ํฐ", "token_type": "Bearer", "expires_in": ์ ํจ ์๊ฐ, "refresh_token": "๊ฐฑ์ ์ ์ํ ํ ํฐ" }๋ด ์๋น์ค๋ ์ด access token์ ํตํด ๋ฆฌ์์ค ์๋ฒ๊ฐ ์ ๊ณตํ๋ API๋ฅผ ์ฌ์ฉํ ์ ์๋ค. access token์ ํค๋๋ก ์ ์กํ๊ฑฐ๋ url์ ํ๋ผ๋ฏธํฐ๋ก ์ ์กํ๋๋ฐ, ๋ณด์ ๋ฉด์์๋ (๋น์ฐํ) ํค๋๋ก ์ ์กํ๋ ๊ฒ์ด ์ข๋ค.
GET /api/apiurl Authorization: Bearer <access token>ํค๋๋ก ์ ์กํ๊ธฐ ์ํด ์ด ํ ํฐ์ ์ฌ์ฉ์๊ฐ ์ฟ ํค ๋๋ ์ธ์ ์ ํตํด ๊ฐ๊ณ ์์ด์ผ ํ๋ค.
์ฌ๋ฐ๊ธ

์์ access token์ ํฌํจํ JSON์ ํ์์ ๋ณด๋ฉด, access token์๋ ์ ํจ ์๊ฐ์ด ์กด์ฌํจ์ ์ ์ ์๋ค. ์ด ์ ํจ ์๊ฐ์ด ๋ง๋ฃ๋๋ฉด ๋ฆฌ์์ค ์๋ฒ๋ ํด๋น access token์ ์ ํจํ์ง ์์ ๊ฒ์ผ๋ก ํ๋จํ๋ค.
์ด ๊ฒฝ์ฐ ๋ด ์๋ฒ๋ refresh token์ ํตํด access token์ ๊ฐฑ์ ํ๋ค. ์ด ๊ณผ์ ์์ refresh token๋ ๊ฐฑ์ ๋ ์๋ ์๊ณ , ์๋ ์๋ ์๋ค.
์ญํ
์ฌ์ฉ์
์ฌ์ฉ์๋ ๋ค์์ ์ํํ๋ค.
๋ก๊ทธ์ธ์ ์๋ (๊ตฌ๊ธ๋ก ๋ก๊ทธ์ธ, ํ์ด์ค๋ถ์ผ๋ก ๋ก๊ทธ์ธ ๋ฑ์ ๋ฒํผ์ ํด๋ฆญ)
์ธ์ฆ์ ๋์ํจ์ผ๋ก์จ ๋ก๊ทธ์ธ์ ์ฑ๊ณตํ๋ค.
๊ฐ๋ฐ์
๊ฐ๋ฐ์๋ ๋ค์์ ์ํํ๋ค.
๋ฆฌ์์ค ์๋ฒ์ ์์ ์ ์๋น์ค๋ฅผ ๋ฑ๋กํ๋ค.
ํด๋ผ์ด์ธํธ ID, ํด๋ผ์ด์ธํธ Secret์ ๋ฐ๊ธ๋ฐ์ ์๋ฒ๊ฐ ์ด๋ฅผ ์ด์ฉํ ์ ์๋๋ก ํ๋ค.
์ธ์ฆ ํ๋ฆ์ 4~8์ ์ํํ๊ธฐ ์ํ API๋ฅผ ๊ตฌํํ๋ค.
์ด ๊ณผ์ ์ ๋จ์ํํ๋ ๋ค์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ์กด์ฌํ๋ค. Spring Security, Passport ๋ฑ์ด ์ด์ ํด๋นํ๋ค.
๋ฆฌ์์ค ์๋ฒ
๋ฆฌ์์ค ์๋ฒ๋ ์ฌ์ฉ์์ ๋ณด์์ ์ํด ๋ค์๊ณผ ๊ฐ์ด ๋์ํ๋ค.
authorization code๋ ํ ๋ฒ ๊ฐฑ์ ์ ๋ง์น ๋ค ์๋ฉธํ๋ค. ์ฆ, ๋งค ๋ฒ ๋ค๋ฅธ code๊ฐ ๋ฐ๊ธ๋๋ค.
access token์ ๋ฐ๊ธ๋ฐ๊ธฐ ์ํด์๋ ๋ฆฌ์์ค ์๋ฒ๊ฐ ์์ ํ client id, client secret, authorization code์ ๊ฐ๋ฐ์๊ฐ ํ๋ผ๋ฏธํฐ๋ก ๋๊ธด ์ธ ๊ฐ์ ๊ฐ์ด ๋ชจ๋ ์ผ์นํด์ผ ํ๋ค.
access token์๋ ์ ํจ ๊ธฐ๊ฐ์ด ์กด์ฌํ๋ค. ์ด ๊ธฐ๊ฐ์ด ์ง๋๋ฉด ๋ฆฌ์์ค ์๋ฒ์์ ์๋ฉธํ๋ฉฐ, ์ฌ๋ฐ๊ธ์ ์ํด refresh token์ ์ด์ฉํด์ผ ํ๋ค.
Reference
Last updated