Bibi's DevLog ๐ค๐
[Codesquad] ๋คํธ์ํฌ - ์ํ&๋ฌด์ํ, ์ฟ ํค, ์ธ์ , ๋ก๊ทธ์ธ ๊ณผ์ , ์คํ๋ง์ผ๋ก ๋ก๊ทธ์ธ ๊ตฌํ, ์ธ์ DB, ์น์์ผ ๋ณธ๋ฌธ
[Codesquad] ๋คํธ์ํฌ - ์ํ&๋ฌด์ํ, ์ฟ ํค, ์ธ์ , ๋ก๊ทธ์ธ ๊ณผ์ , ์คํ๋ง์ผ๋ก ๋ก๊ทธ์ธ ๊ตฌํ, ์ธ์ DB, ์น์์ผ
๋น๋น bibi 2021. 3. 18. 23:50์ค๋์ ํธ๋ ์ค ์์
์ํ(stateful)์ ๋ฌด์ํ(stateless)์ ์ฐจ์ด?
๋ฌด์ํ : ์ฃผ๋ฌธํ์๊ฒ ์ด์? - ์ ์ก๋ฎ๋ฐฅ ํ๋ ์ฃผ์ธ์.
์ํ ์ ์ง : ์ฃผ๋ฌธํ์๊ฒ ์ด์? - ๋ ๋จน๋ ๊ฑธ๋ก ์ฃผ์ธ์.
์ฟ ํค Cookie
ํด๋ผ์ด์ธํธ๊ฐ ๋๊ตฌ์ธ์ง ์๋ณํ๊ธฐ ์ํด, ์น ์๋ฒ๊ฐ ์ฌ์ฉ์์ ์ปดํจํฐ์ ์ค์นํ๋ ์์ ์ ๋ณด ํ์ผ.
''์ฟ ํค''๋ ํจ์ ค๊ณผ ๊ทธ๋ ํ ์์ ์ ๋ํ ํํ์ด๋ค.
์น ์๋ฒ๋ ๋ฌด์ํ(stateless)์ด๊ธฐ ๋๋ฌธ์, ํ์ฌ ์ ์ํ ์ฌ์ฉ์๊ฐ ์ด์ ์ ์ ์ํ ์ฌ์ฉ์์ธ์ง ์๋์ง ์ ์ ์๋ค.
- ๋ก๊ทธ์ธ๊ณผ ๊ฐ์ด, ํ ๋ฒ ๋ก๊ทธ์ธํ ์ํ๊ฐ์ ์ ์งํ ์ ์๋ค.
๊ทธ๋์ ์๋ฒ๋..
์๋ฒ : ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ์์ฒญ์ ๋ฐ์์ ๋, Set - Cookie header๊ฐ์ผ๋ก ์ ์งํ๊ณ ์ถ์ ๊ฐ์ ํด๋ผ์ด์ธํธ์ ์ ์ก(response)ํ๋ค.
ํด๋ผ์ด์ธํธ : ์ดํ ๋ฐ์ํ๋ ๋ชจ๋ ์์ฒญ์ ์๋ฒ๋ก๋ถํฐ ๋ฐ์ Cookie header๊ฐ์ ํจ๊ป ๋ณด๋ธ๋ค.
์๋ฒ : ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ๋ฐ์ ์์ฒญ์ Cookie header๊ฐ์ ๋ณด๊ณ ์ด์ ์ ์ ์ํ ์ฌ์ฉ์์ธ์ง ์๋ณํ๋ค.
์ธ์ Session
: ๋ฐฉ๋ฌธ์๊ฐ ์น ์๋ฒ์ ์ ์ํด ์๋ ์ํ(state)๋ฅผ ํ๋์ ๋จ์๋ก ๋ณด๊ณ , ๊ทธ ๋จ์๋ฅผ ์ธ์ ์ด๋ผ๊ณ ํ๋ค.
์ผ์ ์๊ฐ ๋์ ๊ฐ์ ์ฌ์ฉ์๊ฐ ๋ณด๋ด๋ ์์ฒญ์ ํ๋์ ์ํ๋ก ๋ณด๊ณ , ๊ทธ ์ํ๋ฅผ ์ผ์ ํ๊ฒ ์ ์ง์ํค๋ ๊ธฐ์ ์ด๋ค.
(์ผ์ ์๊ฐ : ์น ๋ธ๋ผ์ฐ์ ๋ฅผ ํตํด ์น ์๋ฒ์ ์ ์ํ ์๊ฐ๋ถํฐ - ์น ๋ธ๋ผ์ฐ์ ๋ฅผ ์ข ๋ฃํด ์ฐ๊ฒฐ์ ๋๋ด๋ ์๊ฐ๊น์ง)
์ธ์ = ์์์ ์ฅ์.
๋ก๊ทธ์ธํ ์ฌ์ฉ์ 1๋ช ๋น 1๊ฐ์ฉ ์๊ธฐ๋ฉฐ, ๊ทธ ์ฌ์ฉ์ ์ ์ฉ ์ ์ฅ์์ด๋ค.
- ์ธ์ ์ Map์ด๋ผ๊ณ ๋ณผ ์ ์๋ค. ํค, ๊ฐ์ผ๋ก ์ ์ ๋ฅผ ์ถ๊ฐํ๋ค.
- ํค = sessionedUser, ๊ฐ = User
- ์ธ์ ์๋ ์ฌ์ฉ์ ๋ฐ์ดํฐ ์ฒ๋ฆฌ์ ํ์์ ์ธ ์ ๋ณด๋ง ๋ด๋๋ค. id(ํ์), name, ๋ฑ๋ฑ
โป ์ธ์
์ ๊ฑฐ์น๋ฉด ๋ณดํต redirect:/main
์ฒ๋ฆฌํ๋ค.
- ์ธ์ ์ ์๋ฒ ์ค์์๋ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅ๋๋ค (๊ธฐ๋ณธ์ ์ผ๋ก). ์ฌ์ฉ์๊ฐ ๋ง์์ง๋ฉด ์ธ์ DB๋ฅผ ๋ง๋ค์ด ์ ์ฅํ๋ค(Redis).
์ธ์ ์๋ ๋ง๋ฃ์๊ฐ์ด ์๋ค.
๋ง์ฝ ์๋ค๋ฉด? - ๋ฉ๋ชจ๋ฆฌ ํญ๋ฐ ๋ฐ ํดํน ๊ฐ๋ฅ.
์ธ์ ์ด ๋ง๋ฃ๋๋ฉด ๋ก๊ทธ์์๋๋ค.
์์ฆ์ ์ธ์ ๋ง๋ฃ์๊ฐ ๋์ refreshํ ํฐ, Authํ ํฐ์ ๋ง๋ค์ด refreshํ ํฐ์ ๊ธธ๊ฒ, Authํ ํฐ์ ์งง๊ฒ ๋ง๋ฃ์๊ฐ์ ์ ํ๋ค.
โ ๋ ๊ณต๋ถํ๊ธฐ : ์ฟ ํค์ ์ธ์ ๋ฐ ์ฐจ์ด์ . ์ฌ๊ธฐ ์์ฒญ๋๊ฒ ์ ๋ฆฌ๊ฐ ์ ๋์ด ์๋ค! ๐๐
์คํ๋ง์ผ๋ก ๋ก๊ทธ์ธ ๊ตฌํํ๊ธฐ
UserController
@RestController
@RequestMapping("/login")
public class UserController {
//์ธ์
. <sessionId, userId>
private Map<String, String> session = new HashMap<>();
@GetMapping
public MyResponse welcome() {
return new MyResponse("ok", "Kite");
}
//์ด ์ํ์์ ์ฑ์ ์คํ ํ `localhost:8080`์ ์ ์ํ๋ฉด `{"status" : "ok", "message" : "Kite"}` ์ ๊ฐ์ JSONํ์(์ ํํ๋ Jackson)์ ๋ฐ์ดํฐ๊ฐ ์ถ๋ ฅ๋๋ค.
@GetMapping("/check")
public MyResponse check(HttpServletRequest req) {
// Cookie๊ฐ์ Http ์์ฒญ์ ๋ค์ด ์๋ค. ๋ฐ๋ผ์ HttpServletRequest
String key = "sid";
String uid = "Null";
Cookie[] cookies = req.getCookies();
for(Cookie c : cookies) {
if (c.getName().equals(key)) {
uid = session.getOrDefault(c.getValue(), "Null");
sout("chcek: " + c.getValue() + ": " + uid);
}
}
return new MyResponse("ok", "login id: " + uid);
}
@PostMapping
public MyResponse login(String id, HttpServletResponse response) {
sout(id);
Random r = new Random();
String sid = Integer.toString(r.nextInt());// ์ธ์
ID : ํด์ฌ๊ฐ ๋์ ๊ฐ๋จํ ๋๋ค์ซ์๋ก ๋ฃ๋๋ค
session.put(sid, id);
sout("login: " + sid + ": " + session.get(sid));
response.addCookie(new Cookie("sid", sid)); // ์ฟ ํค๋ฅผ ์
ํ
ํ๋ค
return new MyResponse("ok", "sid : " + sid)
}
}
MyResponse
public class MyResponse{
private String status;
private String message;
public MyResponse(String status, String message){
this.status = status;
this.message = message;
}
}
๋ก๊ทธ์ธ ๊ณผ์ ์ค๋ช
โ ์ด ๋ก๊ทธ์ธ ๊ณผ์ , โก๊ฐ ๋ก๊ทธ์ธ ์ดํ ์ํ์ด๋ค.
โ ๋ก๊ทธ์ธ
POST / login (DTO๋ก ์ ๋ฌ)
Controller : @PostMapping("/login")
์๋ id, pw๋ HTTP Request์ ๋ค์ด์๋ค. ํ์ง๋ง ์ฐ๋ฆฌ๊ฐ ์ง์ ์ ์ดํ์ง ์๊ณ ์ถ์ํ๋ ๊ฒ์ ์ฌ์ฉํ๋ค.
DB์ ์๋ ํด๋น ์ ์ ์ ๋น๊ตํ๋ค.
id, pw ๋ฑ์ ์ ๋ฌํ ๋
DTO
๊ฐ์ฒด์ ๋ฃ์ด ์ ๋ฌํ๋ ๊ฒ ์ข๋ค.
์ธ์ ์์ด๋ sessionId
๋ก๊ทธ์ธ ๊ณผ์ ์์ ๋ธ๋ผ์ฐ์ ์ ์ฌ์ฉ์๊ฐ ๊ตํํ๋ ๊ฒ์ 'sessionId'๋ฟ์ด๋ค. (๋ฏผ๊ฐ์ ๋ณด๊ฐ ์์ด ๋ณด์์ ์ ๋ฆฌํ๋ค)
์ค์ sessionId๋ ๋งค์ฐ ๊ธธ๊ณ ๋ณต์กํ ๊ฐ(4byte์ ๋). sessionId๋ฅผ ๋ฐ๊ฟ์ ๋ค๋ฅธ ์ฌ์ฉ์๋ก ๋ก๊ทธ์ธํ ๊ฐ๋ฅ์ฑ์ ์์ง๋ง ๊ทธ๋ฌ๊ธฐ๊ฐ ์ด๋ ต๋ค(๊ฑฐ์ ๋ถ๊ฐ๋ฅ)
โก ๋ก๊ทธ์ธ ์ดํ
๋ก๊ทธ์ธ๋ ์ฌ์ฉ์๋ ์ธ์ ์์ด๋ (sessionId, sid)๋ฅผ ์ ์ฅํด ๋ณด๋ด์ ๊ตฌ๋ณํ๋ค.
๋ธ๋ผ์ฐ์ ๋ ์ธ์ ์ ๋ณด ์ ์ฒด๊ฐ ์๋ ์ธ์ ์์ด๋๋ง ์ ์ฅํ๋ค. (๋ณด์, ์ฑ๋ฅ ๋๋ฌธ์) - ์ฟ ํค์ ์ ์ฅํ๋ค!
โข ๋ก๊ทธ์์
๋ก๊ทธ์์ = ์ธ์ ์ ๋ณด ์ญ์ .
๋ก๊ทธ์์์ ๋ณดํต POST /logout
๋ก ์์ฒญํ๋ค. (์ ๋ต์ ์์ง๋ง ์ต๊ด์ ์ผ๋ก)
- ํด๋ผ์ด์ธํธ : ์ฟ ํค์ ์ธ์
์์ด๋๋ฅผ ๋ด์ ์๋ฒ๋ก ๋ณด๋ธ๋ค.
- ์ธ์ id๊ฐ ์ ํจ(valid)ํ๋ฉด ๋ก๊ทธ์์์ด ๋๊ณ , ์ ํจํ์ง ์์ผ๋ฉด HTTP Status Code๋ฅผ ๋ฆฌํดํ๋ค. (๋ณดํต 401 - Unauthorized)
๋ก๊ทธ์์๊ณผ์ :
- ์ธ์ ์ญ์
- ์ฟ ํค์ ๋ง๋ฃ์๊ฐ=ํ์ฌ์๊ฐ์ผ๋ก ๋ด์์ ํด๋ผ์ด์ธํธ๋ก ๋ณด๋ด๊ธฐ
- ํด๋ผ์ด์ธํธ์์ ์ฟ ํค๊ฐ ๋ง๋ฃ๋๋ฏ๋ก ์ญ์ ๋จ
HTTP session์ ์๋ฐ ์๋ธ๋ฆฟ์ ์ํด ์๋ค.
ํ์ ์์๋ ์๋ธ๋ฆฟ ๋์ Spring Security๋ฅผ ์ฌ์ฉํ๋ค - ๋งค์ฐ ์ด๋ ค์ฐ๋ ๋์ค์ ๊ณผ์ ๋๋๊ณ ํด๋ณด๊ธฐ
์๋ ์๋..
- ํด๋ผ์ด์ธํธ๊ฐ ์ฟ ํค์ id, pw๋ฅผ ๋ด์? ์๋ฒ์ ๋ณด๋ธ๋ค.
- ์ฟ ํค๋ ๋ธ๋ผ์ฐ์ ์ ์ ์ฅ๋์ด ์๋ค
- ์ฟ ํค์ ๋ด๊ฒจ์ง id, pw๋ฅผ ๋ณด๊ณ ์๋ฒ๊ฐ DB์ ๋น๊ตํด ๋ก๊ทธ์ธ์ ์ฒ๋ฆฌํ๋ค.
- ์ค์ํ ์ ๋ณด๋ ์ ๋๋ก ํด๋ผ์ด์ธํธ์ ๋ฃ์ผ๋ฉด ์ ๋๋๋ฐ, id pw๋ฅผ ๋ค ๋ฃ์ด ๋ณด๋๊ธฐ ๋๋ฌธ์ ๋ณด์์ ๋งค์ฐ ์ทจ์ฝํ๋ค.
์ธ์ DB (Session DB, SDB)
์ธ์ ์ ์๋ฒ ์ค์์๋ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅ๋๋ค (๊ธฐ๋ณธ์ ์ผ๋ก).
ํ์ง๋ง ์ฌ์ฉ์๊ฐ ๋ง์์ง๋ฉด ์ธ์ ๋ ๋ง์์ง๋ฏ๋ก ๋ฉ๋ชจ๋ฆฌ๊ฐ ํฐ์ง ์ ์๋ค.
๋ฐ๋ผ์ ์ฌ์ฉ์๊ฐ ๋ง์์ง๋ฉด ์ธ์ DB๋ฅผ ๋ง๋ค์ด ์ ์ฅํ๋ค(Redis ๊ฐ์).
์ธ์ ์ ๋ณด๊ฐ ์๋ฒ์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅ๋๋ฉด, ์๋ฒ๊ฐ ์ฌ๋ฌ๋์ผ ๊ฒฝ์ฐ ๋ค๋ฅธ ์๋ฒ์ ์ธ์ ์ ๋ณด๋ฅผ ๋๋๊ธฐ ํ๋ค ๊ฒ ๊ฐ์ต๋๋ค. ์ด๋ด ๋ ์ธ์ ๋๋น๋ฅผ ์ฐ๋๊ฑด๊ฐ์? -> YES.
์ธ์ DB๊ฐ ์์ผ๋ฉด ๊ทธ๊ฑธ ์ฌ์ฉํ๊ณ , (์ธ์ DB๋ฐฉ์)
์ธ์ DB๊ฐ ์์ผ๋ฉด ๋ณ๋์ ์ฑ๋channel์ ๋ง๋ค์ด ๋ชจ๋ ์๋ฒ๋ค๋ผ๋ฆฌ ์ธ์ ์ ๋ณด๋ฅผ ๊ณต์ ํ๋ค.
Case1. Sticky session
๋ก๋๋ฐธ๋ฐ์L7 - SessionDB๊ฐ ํ์์๋ค. ๊ฐ๋ฐ์๊ฐ ์ถ๊ฐ ์ฝ๋๋ฅผ ์์ฑํ ํ์๊ฐ ์๋ค.
๊ฐ ์ฌ์ฉ์๋ง๋ค ์ฌ์ฉํ๋ ์ ์ฉ ์๋ฒ?๊ฐ ์๋ค.
Case2. SDB (์ธ์ DB)
๋ก๋๋ฐธ๋ฐ์L4 - ์ธ์ DB
๋ชจ๋ ์ธ์ ์ ๋ณด๋ ์ธ์ DB์์ ๊ด๋ฆฌ๋๋ค.
Redis๊ฐ์ DB๋ LRU (Least Recently Used)๋ผ๋ ๋ง๋ฃ์๋ช ์ด ์๋ค.
(SDB์ฉ๋๋ณด๋ค ๋ ๋ง์ ์ฌ์ฉ์๊ฐ ์ ์ํ ๊ฒฝ์ฐ ๊ฐ์ฅ ์๋ ์ ์ ์ํ๋ ์ธ์ ์ ๋ง๋ฃ์ํจ๋ค=๋ก๊ทธ์์๋๋ค)
๋ก๋๋ฐธ๋ฐ์๋ HTTPํค๋๋ฅผ ์ฝ๋ ๋ฅ๋ ฅ์ด ์์ด์ผ ํ๋ค. ๊ทธ๋์ผ ์์ฒญ์ ์์๋ณด๊ณ ํธ๋ํฝ์ ๋ชฉ์ ์ง๋ก ๋ถ์ฐํด ์ค๋ค (L7 ๋ก๋๋ฐธ๋ฐ์๋ ์ด ๋ฅ๋ ฅ์ด ์๊ณ , L4๋ ์๋ค. ๊ทธ๋์ L7์ด ๋ ๋น์ธ๋ค)
์น์์ผ WebSocket
HTTP๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ํ๋ฅผ ๊ฐ์ง ์ ์๋ค (๋ฌด์ํ ํ๋กํ ์ฝ์ด๋ค.) (=์ปค๋ฅ์ ์ด ์๋ค?)
ํ์ง๋ง ์์ฆ์ ์ํ๋ฅผ ๊ฐ์ง๊ฒ ํ๊ณ ์ถ์ด์(์ปค๋ฅ์ ์ ์ ์งํ๊ณ ์ถ์ด์) ์น์์ผWebSocket์ด๋ผ๋ ๊ฒ์ด ๋์๋ค.
์น์์ผ์ ์์์ HTTP๋ก ํ์ง๋ง, TCP/IP์์์ ๋์๊ฐ๋ค. (์ฑ๋ฅ์ ์ํด)
๊ถ๊ธํ๊ฒ ์ ๋ stateless ์ ๊ฐ์ฅ ํฐ ์ฅ์ ์ด, ํ์ ๋ connection pool ๋ก๋ ๊ต์ฅํ ๋ง์ ์ฌ์ฉ์์๊ฒ ์๋น์ค๋ฅผ ์ ๊ณตํ ์ ์๋ ์ ์ด๋ผ ์๊ฐํ๊ณ ์๋๋ฐ, ๋ค์ ์น ์์ผ์ผ๋ก ์ปค๋ฅ์ ์ ์งํ๋ฉด ๋๊ท๋ชจ ์ปค๋ฅ์ ์ ์ด๋ป๊ฒ ๊ด๋ฆฌํ๋์?
๊ทธ๋์ ์์ฆ์ ์๋ฒ๊ฐ ๊ต์ฅํ ๋ฌด๊ฑฐ์์ก๋ค. ๋๊ท๋ชจ ํธ๋ํฝ์ ์๋น์ค๋ ์๋ฒ๊ฐ ์ค์ฒ๋.
โ ์ค๋ ๋ด์ฉ์ด ์ด๋ ค์ ๋ค๋ฉด HTTP, TCP/IP ํค์๋ ์ค์ฌ์ผ๋ก ๊ณต๋ถํ๋ฉด ๋๋ค. (์์ ์ฑ ๋ถํฐ ๋ณด์)