API์์ ๊ฐ์ฅ ์์ฃผ ๊ตฌํ๋๋ ๊ธฐ๋ฅ ์ค ํ๋๋ก,
Privateํ API, Publicํ API๋ ๊ธฐ๋ณธ์ ์ธ ์ธ์ฆ๊ณผ ์ธ๊ฐ๋ฅผ ์๊ตฌํ๋ค.
๋ชจ๋ ์ธ์ฆ๊ณผ ์ธ๊ฐ๋ bcrypt ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ค.
์ธ์ฆ์ ์ ์ ์ identification์ ํ์ธํ๋ ์ ์ฐจ๋ก
์ฝ๊ฒ๋งํด ์ ์ ์ ID์ PASSWORD๋ฅผ ํ์ธํ๋ ์ ์ฐจ์ด๋ค.
1. ์ ์ ์์ด๋์ ๋น๋ฒ ์์ฑ (ํ์๊ฐ์
)
2. ์ ์ ๋น๋ฒ ์ํธํ ํด์ DB์ ์ ์ฅ. save()
3. ์ ์ ๋ก๊ทธ์ธ -> ์์ด๋์ ๋น๋ฐ๋ฒํธ ์
๋ ฅ
4. ์ ์ ๊ฐ ์
๋ ฅํ ๋น๋ฐ๋ฒํธ ์ํธํ ํํ ์ํธํ๋์ DB์ ์ ์ ๋ ์ ์ ๋น๋ฐ๋ฒํธ์ ๋น๊ต.
5. ์ผ์นํ๋ฉด ๋ก๊ทธ์ธ ์ฑ๊ณต
6. ๋ก๊ทธ์ธ ์ฑ๊ณตํ๋ฉด `access token`์ ํด๋ผ์ด์ธํธ์๊ฒ ์ ์ก.
7. ์ ์ ๋ ๋ก๊ทธ์ธ ์ฑ๊ณตํ ๋ค์๋ถํฐ๋ `access token`์ ์ฒจ๋ถํด
request๋ฅผ ์๋ฒ์ ์ ์กํจ์ผ๋ก์ ๋งค๋ฒ ๋ก๊ทธ์ธ ํด๋ ๋์ง ์๋๋ก ํ๋ค.
ID
, Email
PassWord ๋ฑ๋ฑ
Password๊ฐ ํนํ ์์ฃผ์์ฃผ ์ค์ํ๋ฉฐ, ๊ฐ์ธ์ ๋ณด๋ณดํธ๋ฒ์ ์ํด
'๋น๋ฐ๋ฒํธ, ๋ฐ์ด์ค, ์ฃผ๋ฏผ๋ฑ๋ก๋ฒํธ ๋ฑ๊ณผ ๊ฐ์ ์ฃผ์ ๊ฐ์ธ์ ๋ณด๊ฐ ์ํธํ๋์ง ์๊ณ ๊ฐ์ธ์ ๋ณด์ฒ๋ฆฌ ์์คํ
์ ์ ์ฅ๋๊ฑฐ๋ ๋คํธ์ํฌ๋ฅผ ํตํด ์ ์ก๋ ๊ฒฝ์ฐ ๋
ธ์ถ ๋ฐ ์ยท๋ณ์กฐ ๋ฑ์ ์ํ์ด ์์ผ๋ฏ๋ก ์ํธํ ๋ฑ์ ์์ ํ ๋ณดํธ์กฐ์น๊ฐ ์ ๊ณต๋์ด์ผ ํ๋ค.'๋ผ๊ณ
๋ช
์๋์ด ์๊ธฐ ๋๋ฌธ์
๊ตญ๊ฐ์์ ๊ถ๊ณ ํ๋ ์์ฉ ์๊ณ ๋ฆฌ์ฆ์ ์ด์ฉํด ๊ฐ์ธ์ ๋ณด๋ฅผ ์ํธํํด์ผ ํ๋ค.
์ฌ์ฉ์์ ๋น๋ฐ๋ฒํธ๋ '๋น๋ฐ'๋ฒํธ์ธ ๋งํผ ์ํธํํ์ฌ ์ ์ฅํด์ผํ๋ค.
๊ทธ๋ผ ์ํธํํ์ฌ ์ ์ฅํ๋ ๊ฑด ์ด๋ป๊ฒ ํด์ผํ ๊น?
๋น๋ฐ๋ฒํธ ์ํธํ์๋ '๋จ๋ฐฉํฅ ํด์ฌ ํจ์(one-way hash function)'๊ฐ ์ฐ์ธ๋ค.
์
๋ ฅ๋ฐ์ ๋ฉ์์ง๋ฅผ ์ํธํํ์ฌ ์ ์ฅํ๊ณ ,
์ํธํ๊ฐ ๋ ๋ฉ์์ง๋ ์๋ณธ์ผ๋ก ๋๋ฆด ์ ์์ด ๋จ๋ฐฉํฅ์ฑ(one-way)๋ผ๊ณ ํ๋ค.
ex) ํ ์ฌ์ดํธ์ ๋น๋ฐ๋ฒํธ๋ฅผ ์์ด๋ฒ๋ ธ๋ค๊ณ ํ์ ๋, ๋น๋ฐ๋ฒํธ๋ฅผ ์๋ ค์ฃผ๋ ํ๋ก์ธ์ค๊ฐ ์๋ ๋น๋ฐ๋ฒํธ ์ฌ์ค์ ํ๋ก์ธ์ค๊ฐ ๋์ค๋ ๊ฑธ ์๊ฐํ๋ฉด ์ฌ์
๋ง์ฝ 1234
๋ฅผ SHA-256
๋จ๋ฐฉํฅ ํด์ฑํ๋ค๊ณ ๊ฐ์ ํ์ ๋์ ๊ฒฐ๊ณผ๊ฐ์
03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4
์ด๋ค.
import hashlib
a = hashlib.sha256()
a.update(b"test password")
a.hexdigest()
a.hexdigest()
# output
03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4
๊ฒฐ๊ณผ๋ง ๋ด์๋ ์๋ฒฝํ ์ํธํ์ธ ๊ฒ ๊ฐ์ง๋ง,
์๊ณ ๋ฆฌ์ฆ์ผ๋ก 1234
๋ฅผ ๋ค์ ํด์ฑํ๋ฉด ํญ์ ๊ฐ์ ๊ฐ์ด ๋์ถ๋๋ค.
์ด์ ๊ฐ์ ์ทจ์ฝ์ ์ ์ด์ฉํ์ฌ ๋ชจ๋ ํด์ฑ ๊ฒฝ์ฐ์ ์๋ฅผ ํด์๊ฐ์ผ๋ก ๋ณ๊ฒฝํ์ฌ ํ๋งคํ๋ ์๋น์ค๋ ์กด์ฌํ๋ค. ๋ถ๋ค๋ถ๋ค
signature = ์๋ช
๋ด๊ฐ ๋ง๋ค์ด์ค ๊ทธ ๊ฐ์ด ์ผ์นํ์ง ์๋์ง ํ์ธํ๋ ๊ณผ์
ํ๋ก ํธ์์ JWT๋ฅผ ๋ฐฑ์๋ API ์๋ฒ๋ก ์ ์กํ๋ฉด ์ ์ก๋ฐ๋ JWT์ ๊ฐ์ด ์ผ์นํ๋์ง ํ์ง ์๋์ง ํ์ธํ๋ค.
์ ์ ๊ฐ ๋ก๊ทธ์ธ์ ์ฑ๊ณตํ ํ์๋ access token
์ด๋ผ๊ณ ํ๋ ์ํธํ๋ ์ ์ ์ ๋ณด๋ฅผ ์ฒจ๋ถํด์ request๋ฅผ ๋ณด๋ด๊ฒ ๋๋ค.
access token
์ ์์ฑํ๋ ๋ฐฉ๋ฒ์๋ ์ฌ๋ฌ๊ฐ์ง๊ฐ ์๋๋ฐ, ๊ทธ ์ค ๊ฐ์ฅ ๋๋ฆฌ ์ฌ์ฉ๋๋ ๊ธฐ์ ์ค ํ๋๊ฐ JWT์ด๋ค.
JWT๋ ๋ง ๊ทธ๋๋ก ์ ์ ์ ๋ณด๋ฅผ ๋ด์ JSON ๋ฐ์ดํฐ๋ฅผ ์ํธํ ํด์ ํด๋ผ์ด์ธํธ์ ์๋ฒ๊ฐ์ ์ฃผ๊ณ ๋ฐ๋ ๊ฒ์ด๋ค.
์ ์ ๋ก๊ทธ์ธ
POST /auth HTTP/1.1
Host: localhost:5000
Content-Type: application/json
{
"username": "joe",
"password": "pass"
}
access token
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eSI6MSwiaWF0IjoxNDQ0OTE3NjQwLCJuYmYiOjE0NDQ5MTc2NDAsImV4cCI6MTQ0NDkxNzk0MH0.KPmI6WSjRjlpzecPvs3q_T3cJQvAgJvaQAPtk1abC_E"
}
๊ทธ๋ฌ๋ฉด ์๋ฒ์์๋ access token
์ ๋ณตํธํํด์ ํด๋น ์ ์ ์ ๋ณด๋ฅผ ์ป๊ฒ๋๋ค.
# ์๋ฅผ ๋ค์ด access token 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZGVudGl0eSI6MSwiaWF0IjoxNDQ0OTE3NjQwLCJuYmYiOjE0NDQ5MTc2NDAsImV4cCI6MTQ0NDkxNzk0MH0.
KPmI6WSjRjlpzecPvs3q_T3cJQvAgJvaQAPtk1abC_E' ์ ๋ณตํธํ ํ๋ฉด,
{
user_id = 1
}
๊ฐ์ด ๋์จ๋ค.
Authorization์ ์ ์ ๊ฐ ์์ฒญํ๋ request๋ฅผ ์คํํ ์ ์๋ ๊ถํ์ด ์๋ ์ ์ ์ธ๊ฐ๋ฅผ ํ์ธํ๋ ์ ์ฐจ ์ด๋ค.
stateless > ๋ก๊ทธ์ธ ์์ฒญ๊ณผ ๋ก๊ทธ์ธ ํ ์ ์ ๊ฐ ํด๋น ์ฌ์ฉ์๊ฐ ๋ง๋์ง ํ์ธํ๋ ์์ฒญ์ ๋
๋ฆฝ์ ์ด๋ค.
access token์ ํตํด ํด๋น ์ ์ ์ ๋ณด๋ฅผ ์ป์ ์ ์์์ผ๋ก ํด๋น ์ ์ ๊ฐ ๊ฐ์ง๊ณ ์๋
๊ถํ(permission)๋ ํ์ธ ํ ์ ์๋ค.
๋งค http ์์ฒญ๋ง๋ค headers์ meta data๋ก ์
๋ ฅ๋๋ค.
๊ธฐ์กด ๋ฐฉ์์ ๋จ์ ์ ๋ณด์ํ JWT ๋ก์ง ์๋ฒ์ ์๋ฒ๊ฐ ์ํฌ๋ฆฟํค๋ฅผ ๊ณต์ ํ์ฌ ์ฌ์ฉํ๋ค.
1. http ์์ฒญ(๋ก๊ทธ์ธ)
2. ์ ์ ์ ๋ณด ํ์ธ ํ ํด๋น ์ ๋ณด์ ์๋ฒ์ SECRET KEYํ์ฉํ์ฌ JWT์์ฑ
3. ํด๋น JWT ์ ์ก
4. JWT๋ฅผ ๋ธ๋ผ์ฐ์ ์ ์ ์ฅ
5. JWT๋ฅผ ํฌํจํ http ์์ฒญ
6. JWT์ Signature ๋ถ๋ถ์ ํ์ธ ํ ํด๋น ์ ์ ์ ๋ณด ๊ฒ
7. HTTP ์๋ต