๊ฐ์
์ฐ์ ์ฐ๋ฆฌ ํ๋ก์ ํธ๋ ๋ณ๋์ ๋ก๊ทธ์ธ/ํ์๊ฐ์
์ ์ฐจ ์์ด ์์ฆ ๋ง์ด ์ฌ์ฉํ๋ Oauth2๋ฐฉ์์ ์ฌ์ฉํ๊ธฐ๋ก ๊ฒฐ์ ํ๋ค. ์ด์ ๋ ํ๋ก ํธ ์ชฝ ๊ตฌํํ ๋๋ ์์
ํ ์ ์์ฒด๊ฐ ์ค์ด๋ค๊ธฐ๋ ํ๊ณ ๋๋ ๊ณต๋ถํ๋ฉด์ ํ ์ ์์ ๊ฒ ๊ฐ์๋ค.
๊ธฐ๋ณธ ๋ชฉํ
Github OAuth๋ก ๋ก๊ทธ์ธํ ์ฌ์ฉ์๋ฅผ ๋ฐ์, ์๋น์ค์ ๋ฑ๋กํ๊ณ , JWT ํ ํฐ์ ๋ฐ๊ธํด์ API ํธ์ถํ ๋๋ง๋ค ์ธ์ฆํ๋ ์์คํ ์ ๊ตฌ์ฑํ ๊ณํ์ด๋ค.
ํฐ ํ๋ฆ ๋ณด๊ธฐ
- Client ์ฌ์ฉ์๊ฐ โGitHub ๋ก๊ทธ์ธ ๋ฒํผ ํด๋ฆญโ -> /api/auth/github ์์ฒญ
- GitHub OAuth ํ๋ฉด์ผ๋ก ๋ฆฌ๋ค์ด๋ ํธ
- ์ฌ์ฉ์ GitHub ๋ก๊ทธ์ธ ํ ์ธ์ฆ ์ฝ๋ ๋ฐ๊ธ
- /api/auth/github/callback?code=์ธ์ฆ์ฝ๋ ํธ์ถ
- ์ธ์ฆ์ฝ๋๋ก GitHub AccessToken ์์ฒญ
- GitHub ์ฌ์ฉ์ ์ ๋ณด ์กฐํ
- DB์ ์ฌ์ฉ์ ์ ์ฅ ๋๋ ์ ๋ฐ์ดํธ
- JWT AccessToken, RefreshToken ๋ฐ๊ธ
- ํด๋ผ์ด์ธํธ ์ ์ฅ ํ ์ดํ ์์ฒญ ์ Authorization Bearer ํ ํฐ์ผ๋ก ์ธ์ฆ
์ฃผ์ ๊ฐ๋
OAuth๋?
์ฝ๊ฒ ๋งํ๋ฉด ๋ค๋ฅธ ์๋น์ค์ ๋ก๊ทธ์ธํ ๊ณ์ ์ผ๋ก ์ฐ๋ฆฌ ์๋น์ค๋ฅผ ์ด์ฉํ๋ ๊ฒ์ ๋งํ๋ค. ์ง์ ์ฐ๋ฆฌ ์๋น์ค์ ์์ด๋ ๋น๋ฒ์ ์ ๋ ฅํ์ง ์๋๋ฐฉ์์ด๋ค
JWT(Json Web Token)๋?
์ฌ์ฉ์๊ฐ ์ธ์ฆ๋์์์ ์ฆ๋ช ํ๋ โ๋์งํธ ํ ํฐโ์ ๋งํ๋ค. ๋ณ๋์ DB ์กฐํ์์ด๋ ์ ์ด ํ ํฐ์ ๊ฐ์ง๊ณ ์์ผ๋ ์ด ์ฌ์ฉ์๋ ์ธ์ฆ ๋ฐ์ ์ฌ์ฉ์์ผ ๋ผ๊ณ ์ ์ ์๋ค.
ํต์ฌ ๊ตฌ์กฐ ์์ฝ
์ฃผ์ ๋์ ์์ธํ..
GitHub ๋ก๊ทธ์ธ ์์
- /api/auth/github ํธ์ถ
- ์ง์ ๋ OAuth ์ ๊ณต์์ ๋ํ ์ธ์ฆ URL ๋ฐํํด์ค๋ค -> ์ฌ๊ธฐ์ GITHUB
- OAuth ์ ๊ณต์๊ฐ ์ฐ์ ์ง๊ธ์ github๋ก๋ง ๋์ด์๋๋ฐ ๋ ์ถ๊ฐ๋ ์๋ ์์ด์ factory๋ฅผ ๋ง๋ค์ด์ ๋ฏธ๋ฆฌ ๋ฑ๋ก์ ์์ผ๋๊ณ , ํ์ํ๊ฑฐ ๊บผ๋ด์ ์ฐ๋๋ก ๊ตฌํ์ ํ๋ค.
- ๋ก๊ทธ์ธ url์ ์์ฑํ๋ ๊ณผ์ . ์ฌ์ฉ์๊ฐ GitHub์ ๋ก๊ทธ์ธํ๋ฌ ๊ฐ ์ ์๋๋ก ์ ์ ํ ์ฟผ๋ฆฌํ๋ผ๋ฏธํฐ๋ฅผ ๋ถ์ธ URL ์ ๋ง๋ค์ด์ค๋ค
- .encode๋ฅผ ์ง์ ํด์ฃผ์ง ์์ผ๋ฉด URI.create() ํ ๋ โuser:email read:userโ์ด๋ ๊ฒ ๊ทธ๋๋ก ๋ค์ด๊ฐ๊ฒ ๋ผ์ ์ค๋ฅ๊ฐ ๋๋ค.
https://github.com/login/oauth/authorize?client_id=xxx&redirect_uri=xxx&scope=user:email%20read:user
-> ์ฌ์ฉ์์ ์ด๋ฉ์ผ์ด๋ ๊ธฐ๋ณธ ์ฌ์ฉ์ ์ ๋ณด๋ง ์ฝ์ด์ค๋
์ด์ ๋ฆฌ๋ค์ด๋ ํธ๋์ github OAuth๋ก ์ด๋ํจ
GitHub ์ฝ๋ฐฑ ์์
- ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธ ์ฑ๊ณตํ๋ฉด code๊ฐ ๋ด๊ฒจ์ /api/auth/github/callback?code=xxx๋ก ์ด๋ํ๋ค.
- ์๋ฒ๊ฐ ์ด ์ฝ๋๋ฅผ ์ด์ฉํด์
- AccessToken ์์ฒญ
- ์ฌ์ฉ์ ์ ๋ณด ์กฐํ
- DB์ ์ฌ์ฉ์ ์ ์ฅ ๊ทธ๋ฆฌ๊ณ JWT ํ ํฐ์ ๋ฐ๊ธํด์ ํด๋ผ์ด์ธํธ์ ์ ๋ฌํ๋ค.
- ์ธ์ฆ ์ฝ๋๋ฅผ github์๊ฒ post ์์ฒญ์ ๋ณด๋ด์ ์๊น ๋ฐ์ code๋ฅผ access_token์ผ๋ก ๋ฐ๊พผ๋ค.
- ์ด์ access token์ Authorization ํค๋์ ๋ฃ๊ณ github api ํธ์ถํด์ ๋ก๊ทธ์ธํ ์ฌ์ฉ์์ ์ ๋ณด๋ฅผ ๋ฐ์์จ๋ค.
1
2
3
4
5
6
7{ "id": 123456, "name": "ํ๊ธธ๋", "login": "hong", "email": "hong@example.com", "avatar_url": "https://avatars.githubusercontent.com/u/123456?v=4" }
- ๊ทธ๋ค์ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ Member๋ก ๋ณํํ๋ค. -> DB์ ์ฌ์ฉ์ ์ ๋ณด ์ ์ฅ
- ์ด์ ์ธ์ฆ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค.
- Spring Security๊ฐ ์๊ตฌํ๋ ํ์ค ์ฌ์ฉ์ ์ ๋ณด ํฌ๋งท์ ๋ง์ถฐ์ Spring Security๊ฐ ์ดํดํ ์ ์๋๋ก ๋ณํํ๋ค. => โ์ด ์ฌ๋์ provierUid๋ฅผ ์์ด๋๋ก ๊ฐ์ง ์ฌ์ฉ์์ด๊ณ , ์ญํ ์ ROLE_XXX์ผโ
- ์ด์ ์ด ์ฌ์ฉ์๊ฐ ๋๊ตฐ์ง, ์ด๋ค ๊ถํ์ ๊ฐ์ก๋์ง Spring Security๊ฐ ์ ์ ์๊ฒ ๋์๋ค.
- ๊ทธ๋ค์ JWT ํ ํฐ์ ์์ฑํ๊ณ TokenDto๋ก ๋ฌถ์ด์ ๋ฐํํ๋ค.
- TokenDto์๋ accessToken(์ก์ธ์ค ํ ํฐ), refreshToken(๋ฆฌํ๋ ์ ํ ํฐ), tokenType(Bearer ์ผ๋ฐ์ ์ผ๋ก), expriresln(๋ง๋ฃ์๊ฐ (์ด))
API ์์ฒญ์ ์ธ์ฆ ์ฒ๋ฆฌ
- ์ด์ ํด๋ผ์ด์ธํธ๋ ์ดํ ๋ชจ๋ API ์์ฒญ์
Authorization: Bearer {accessToken}
ํค๋๋ฅผ ๋ถ์ฌ์ ๋ณด๋ธ๋ค.(๋ก๊ทธ์ธ ์ํ ์ฌ์ฉ์๋ ๋ณผ ์ ์๋ ๊ฒฝ๋ก๋ ์ ์ธํ๊ณ ) JwtAuthenticationFilter
๊ฐ ์ด ํ ํฐ์ ์ฝ์ด์- ์ ํจํ์ง ๊ฒ์ฆ
- ์ฌ์ฉ์ ์ธ์ฆ(Authentication ๊ฐ์ฒด ์์ฑ)ํด์ SecurityContextHolder์ ์ ์ฅ
- ๊ทธ๋์ ์ดํ ์๋น์ค ๋ก์ง์์ ๋๊ฐ ์์ฒญํ๋์ง ๋ฐ๋ก ์ ์ ์๋ค.
JWTAuthenticatinFilter
- ๋ชจ๋ HTTP ์์ฒญ์ ์ด ํํฐ๋ฅผ ์ง๋๊ฐ๋ค.
- Authorization ํค๋๊ฐ ์๊ฑฐ๋ Bearer ๋ก ์์ํ์ง ์์ผ๋ฉด null๋ฅผ ๋ฐํํ๋ค.(์ธ์ฆ ์๋ ์์ฒด๋ฅผ ์ํ๋ค)
Bearer eyJhbGciOiJIUzUxMiJ9...
-> eyJhbGciOiJIUzUxMiJ9โฆ ์ด ํ ํฐ๋ง ์ถ์ถํ๋ค.
- ์ ํจํ ํ ํฐ์ด๋ฉด
- JWT๋ฅผ ํ์ฑํด์ Claims(=์์ ๋ด๊ธด ๋ฐ์ดํฐ)๋ฅผ ๊บผ๋ด๊ณ
- Claims์์ ๊ถํ ์ ๋ณด๋ฅผ ๊บผ๋ด๊ณ
- Claims์์ ์ฌ์ฉ์ ID๋ฅผ ๊บผ๋ด๊ณ
- UserDetails ๊ฐ์ฒด ์์ฑํ๊ณ
- UsernamePasswordAuthenticationToken์ผ๋ก ๊ฐ์ธ์ ๋ฐํ์ ํ๋ค.
- ์ธ์ฆ ์ ๋ณด ์ ์ฅ์ ํ๋ค.(SecurityContextHolder.getContext().setAuthentication(authentication))
- SpringSecurity๋ ์์ฒญ ํ๋ํ๋๋ง๋ค SecurityContext๋ฅผ ๋ค๊ณ ๊ด๋ฆฌ๋ฅผ ํ๋๋ฐ ์ฌ๊ธฐ๋ค๊ฐ โ์ด ์์ฒญ์ ์ด๋ค ์ฌ์ฉ์๊ฐ ๋ณด๋๋คโ๋ ์ ๋ณด๋ฅผ ์ ์ฅ์ ํ๋ค.
- ์ดํ์ ์๋น์ค ๋ ์ด์ด ์์๋ ํ์ฌ ๋ก๊ทธ์ธํ ์ฌ์ฉ์๋ฅผ ๊บผ๋ด์ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ค.
- ์ด์ ์ธ์ฆ์ด ์ฑ๊ณตํ ํ์ ํํฐ ์ฒด์ธ ๋ค์๋จ๊ณ๋ก ๋์ด๊ฐ๋ฉด์ ์ปจํธ๋กค๋ฌ์ ์ง์ ํ๋ค.