Local storage, Session Storage, Cookie
๐ฅ Local storage VS Session Storage
๐ซ Local storage
- Lifespan: ์๊ตฌ์ ์ธ ์ ์ฅ์
์ฌ์ฉ์๊ฐ ์๋์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ๊ฑฐ๋ ๋ธ๋ผ์ฐ์ ์บ์๋ฅผ ์ง์ฐ์ง ์๋ ์ด์ ์๊ตฌ์ ์ผ๋ก ๋ณด๊ด ๋ก๊ทธ์์ ํ์๋ ๋ฐ์ดํฐ ๋จ์ ์์ - Scope: ๋๋ฉ์ธ ๋ณ๋ก ์ ์ฅ
๋๋ฉ์ธ๋ณ๋ก ์ ์ฅ๋๋ฉฐ, ๋์ผํ ๋๋ฉ์ธ์์๋ง ๋ฐ์ดํฐ ์ ๊ทผ ๊ฐ๋ฅ
shared across all tabs/windows from the same orgin(same protocoal, domain, port)
accessible in another tab/window from the same orgin
v - Storage Limit: ์ฉ๋
๋๋ถ๋ถ ๋ธ๋ผ์ฐ์ Local storage ์ฉ๋์ 5~10MB
๐ญ Session Storage
- Lifespan: ์ผ์์ ์ธ ์ ์ฅ์
๋ธ๋ผ์ฐ์ ์ ํญ, ์ฐฝ์ ๋ซ์ผ๋ฉด ์๋์ผ๋ก ๋ฐ์ดํฐ ์ญ์
์ผ์์ ์ธ ๋ฐ์ดํฐ ์ ์ฅ์ ์ ํฉ - Scope: ํญ๋ณ๋ก ์ ์ฅ, page session
๊ฐ ๋ธ๋ผ์ฐ์ ํญ๋ณ๋ก ์ ์ฅ
each brower tab or window has its own session storage and is not accessible in another tab/window - Storage Limit: ์ฉ๋
๋๋ถ๋ถ ๋ธ๋ผ์ฐ์ Session storage ์ฉ๋ ๋ง์ฐฌ๊ฐ์ง๋ก 5~10MB
๐ช cookie
1๏ธโฃ ์๋ฒ์์ ์ฟ ํค ์ค์
์๋ฒ์์ ์ฌ์ฉ์๊ฐ ์ธ์ฆ์ด ๋๋ฉด, JWT ํ ํฐ์ ์์ฑํ๊ณ ์ด๋ฅผ ์ฟ ํค์ ์ ์ฅ
token = jwt.encode({"user_id": user_id}, SECRET_KEY, algorithm="SH256")
์ฟ ํค๋ ๋ง์ฐฌ๊ฐ์ง๋ก HTTP ์๋ต ํค๋์ Set-Cookie๋ฅผ ์ค์ ํ์ฌ ํ ํฐ์ ์ ๋ฌ
response.set_cookie()
response.set_cookie(key="access_token", value=token) <br>
2๏ธโฃ ํด๋ผ์ด์ธํธ์์ ์ฟ ํค ์ฌ์ฉ
ํด๋ผ์ด์ธํธ์์๋ ์๋ฒ๋ก๋ถํฐ ๋ฐ์ ์ฟ ํค๋ฅผ ์ฌ์ฉํ์ฌ ํ ํฐ์ ์ ์ฅ
์ฟ ํค๋ ๋ธ๋ผ์ฐ์ ์ ์ํด ์๋์ผ๋ก ์ ์ฅ
์๋ฒ๋ก ์์ฒญ์ ๋ณด๋ผ ๋๋ง๋ค ์ฟ ํค๊ฐ ์๋์ผ๋ก ํฌํจ
3๏ธโฃ ์๋ฒ์์ ์ฟ ํค ์ฝ๊ธฐ
์๋ฒ์์๋ ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ๋ฐ์ ์์ฒญ์ ์ฟ ํค๋ฅผ ํ์ธํ์ฌ JWT ํ ํฐ์ ์ถ์ถํ๊ณ ์ธ์ฆ
Request
async def get_token(request: Request): return request.cookies.get("access_token")
๐ก ์ฃผ์!
๋จ, ์ฟ ํค๋ฅผ ์ฌ์ฉํ ๋ HttpOnly์ Secure ํ๋๊ทธ๋ฅผ ์ค์ ํ์ฌ ์ฟ ํค์ ๋ณด์์ ๊ฐํํด์ผ ํ๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from fastapi import FastAPI, Response, Request, Depends
import jwt
app = FastAPI()
@app.post("/login")
async def login(response: Response):
# ์ฌ์ฉ์ ์ธ์ฆ ๋ก์ง
# ...
# JWT ํ ํฐ ์์ฑ
token = jwt.encode({"user_id": user_id}, SECRET_KEY, algorithm="SH256")
# ์๋ต ํค๋์ ์ฟ ํค ์ค์
response.set_cookie(key="access_token", value=token)
return {"message": "๋ก๊ทธ์ธ ์ฑ๊ณต"}
async def get_token(request: Request):
return request.cookies.get("access_token")
@app.get("/protected")
async def protected_route(token: str = Depends(get_token)):
# ํ ํฐ ๊ฒ์ฆ ๋ฐ ์ธ์ฆ ๋ก์ง
# ...