1. HTTP
- HTTP0.9 > 1.0 > 1.1 (가장 많이 사용됨) > 2 > 3
동일한 URI에서 리소스의 서로 다른 버전을 제공하기 위해 사용하는 메커니즘으로, 사용자 에이전트가 사용자에게 제일 잘 맞는 것이 무엇인지(예를 들어, 문서의 언어, 이미지 포맷 혹은 컨텐츠 인코딩에 있어 어떤 것이 적절한지)를 명시할 수 있다.
- Accept MIME 타입으로, 클라이언트가 이해 가능한 컨텐츠 타입이 무엇인지 알려줌. 가중치(q) 부여. 서버가 줄 수 있는 것 중 가장 높은 q를 가진 것 선택. (우선순위)

html(q=0.5)보다 json(q=0.9)가 가중치가 높으므로 json으로 처리됨.

: image/png에 해당하는 것이 없으므로 그 다음 가중치인 html으로 처리됨.
Accept header: 컨텐츠 협상 메커니즘에 활용되는 http header
- 클라이언트의 기기 / 브라우저 환경에 따라 받아서 처리할 수 있는 형식이 다름
- API를 호출하는 소비자쪽마다 원하는 데이터 형식이 다름
- 클라이언트가 어떤 형식을 선호하는지 서버에게 알려주어야 함
- 서버는 Accept header를 보고 가장 적절한 응답 포맷을 선택해서 내려주는 것
⇒ 즉, 클라이언트가 원하는 응답 형식(MIME)을 서버에게 알려주고, 서버가 그것을 참고해서 최적의 응답 포맷을 선택하는 방식
- 클라이언트는 선호하는 포맷을 여러 개 보낼 수 있음
- 서버는 그 중 "지원 가능한 포맷 + q값(가중치)"의 조합을 기준으로 적절한 포맷을 응답
- 서버는 지원 가능한 포맷일 경우 해당 포맷으로 응답
- 그렇지 않으면, 다른 포맷으로 응답 (ex. image/png는 지원하지 않는 경우)
Content-Type header
서버가 결과적으로 응답할 때 사용된 실제 포맷
클라이언트에서는 해당 포맷을 참고하여 적절한 파싱/렌더링 처리를 수행함.
정상 응답 시

Content-type과 보낸 게 맞지 않을 때

// ============================================================
// 2) HTML 문서를 text/plain 으로 응답하여 브라우저 렌더링을 깨뜨리는 테스트
// ============================================================
if (url === "/wrong-content-type" && method === "GET") {
// 실제 HTML을 보낼 건데, Content-Type은 의도적으로 text/plain으로 설정
res.statusCode = 200;
res.setHeader("Content-Type", "text/plain; charset=utf-8");
return res.end(`
<html>
<head><title>잘못된 Content-Type 테스트</title></head>
<body>
<h1>이 HTML은 브라우저에서 렌더링되지 않음</h1>
<p>서버가 Content-Type을 text/plain으로 설정했기 때문</p>
</body>
</html>
`.trim());
}
: html으로 content type을 받았지만
text plain으로 받았기 때문에 텍스트 그대로 화면에 찍힘 (not rendering)
+) 인코딩 빼먹을 경우

정상적으로 렌더링되는 경우

서버가 content-type을 생략할 경우

Cookie vs Session
Cookie
: 사용자의 브라우저에 저장되는 작은 데이터 조각 ex.) 장바구니
Session
: 서버 측에서 사용자 정보를 저장하는 방식
ex.) 로그인하면 정보 암호화해서(세션id) map 객체에 저장해둠.
map 객체에 key, value로 저장해둠
key: session id (예측 불가능하게 만들어야 함)
value: 만료되는 시간, 사용자 id 등..
- createSession()
- session tracking
- http: stateless
- 각 요청을 날릴 때마다. 각 요청이 독립적.
- 로그인 유지 안됨
- stateful하게 만들기 위해서는?
- 사용자 로그인 후. 서버가 만들어준, 사용자를 식별할 수 있는 값을 가져다가 클라이언트에게 전달. 그 값으로 사용자 식별
- stateful한 것처럼 통신하게 함.
- ⇒ session tracking!
- 세션을 계속 추적한다.
- 쿠키 활용
- 브라우저에 저장된 쿠키 중에서 인증 상태(세션)와 관련된 쿠키를 통상적으로 세션쿠키라 한다.
- jwt
- stateless로 할 수 있음
- access token 사용
- 우리금융
- session으로 함(not jwt)
- 보안때문에. 탈취되면 안 되기 때문.
- jwt도 토큰 탈취되면 똑같지 않은지? -> (...)
실습: Cookie, Session
로그인 시 sessionId를 cookie로 설정

생성된 sessionId를 직접 cookie 값으로 넣어줘도 유저 정보 조회 가능

플로우 요약
로그인
-
클라이언트에서 ID/PW로 로그인 수행
-
서버는 저장해서 승인
- DB와 자격증명정보(Credential)가 일치하면 서버에서 세션을 생성해서 클라이언트에게 응답
→ 브라우저에게 쿠키에 보관하라고 응답
: 이때 사용되는 헤더이름 ‘Set-Cookie’: ‘sessionId={문자열}’
-
브라우저는 응답 데이터에서 헤더 중에 Set-Cookie를 보고 Cookie에 저장(sessionId)
— (로그인 끝)
내 정보 조회 플로우
- 클라이언트는 내 정보 보기 버튼을 클릭함 (/userinfo 엔드포인트 호출)
- 서버가 특정 클라이언트(A or B … ) userinfo로 요청받음
- 서버는 클라이언트가 요청을 보낸 요청 객체 중 요청 헤더에서 Cookie 꺼내 파싱. (sessionId에 해당하는 키가 있으면, 세션 저장소(Map 객체, In-memory로 되어있음. 서버 꺼지면 날아감)에서 해당 sessionId와 일치하는 키가 있는지 찾고
있으면, 만료 상태 등 확인,
유효하면,
userinfo에 대한 리소스를 응답.
만약, 해당하는 sessionId가 없으면, “로그인하세요” 응답
만료되었으면, “만료되었어요” 응답
- 유효하면 클라이언트는 “내 정보” 페이지를 조회할 수 있음.
본질적으로는 식별자 << 왔다갔다 하게 해서 주고받음.
서버와 클라이언트만이 아는 무언가! (sessionId)
(+)
in java,
sessionId > JsessionId 로 만들어짐
⇒ 이러한 인증 플로우에 활용되는 HTTP 헤더
2. HTTPS
http 문제점: ‘누구나’ 인터넷을 경유하는 정보를 확인하고 교환할 수 있게 됨 -> 보안 문제! -> HTTPS
- 메시지 해시화 되지 않음 > 데이터 무결성 보장 어려움, 데이터 도청 가능
- 인증서 없음 > 호스트 주소가 바뀌어서(유사사이트) ID, PW 털릴 수 잇음.
- -> 데이터 도청/변조 문제, 상대방 신뢰 문제를 https 가 해결해준다 !
- 도청/변조 > 암호화
- 신뢰 문제 > 인증서 발급
*HTTPS = HTTP + SSL/TLS(보안 프로토콜 레이어)*
(S = Secure)
⇒ HTTP가 데이터 전송 목적의 프로토콜이라면, HTTPS는 데이터가 안전하게 전송되도록 도와주는 프로토콜
해결 방식
- 암호화 (Encryption)
- 해시화 (Hashing)
- 인증 및 인증서 발급 (Certificate)
- 국가 및 국가가 신뢰할 수 있는 기관에서 발급한 디지털 인증서 활용 > 사용자가 접속하려는 페이지가 실제 페이지가 맞는지 확인 가능
SSL (Secure Socket Layer)
웹 브라우저 시장을 열면서 웹에서 안전하게 결제하고 로그인할 방법 (인수되면서 TLS 로 명칭 변경)
TLS (Transport Layer Security)
TCP 연결 이후 수행되며, 이름 그대로 전송 계층에서 데이터를 안전하게 보호하기 위한 프로토콜
1.2 ver >> 젤 많이 씀
1.3 ver >> 핸드셰이킹 단계 간소화 및 속도 향상
- TLS 세부 단계
- 인증서 준비
- 핸드셰이크(Handshake)
- 클라이언트 ~ 서버가 서로를 확인한 이후 암호화된 통신을 수행하기 위해 사용할 암호화 알고리즘 및 키 교환 과정을 거침. >> 이 과정을 핸드셰이크라고 함
- 데이터 암호화 통신
- 핸드셰이킹이 성공적으로 완료되면, 클라이언트와 서버는 데이터를 암호화하여 통신을 수행할 수 있게 됨 > HTTPS 연결이 성공하여 지속적인 데이터 교환이 발생하는 단계 > 핸드셰이크 단계에서 결정된 암호화 및 해시화 알고리즘을 기반으로 데이터 암호화/해시화가 이루어짐
- 대칭키 암호화 알고리즘
- 암호화 키 공유 후 (키, 메시지) 이런 식으로 통신
- 문제점
- 교환 대상자가 여러 명일 경우
- 직접 만나서 암호화 키를 공유하지 못하는 경우
- 개선
- 공유 키, 개인 키 존재
- 공개 키 + 개인 키 서로에게 보냄
- 받은 키 + 개인 키 = 공유 키 + 상대 개인 키 + 자기 개인 키 의 공통값을 가지게 됨 << 이걸로 통신. ⇒ 서로 같은 키 가지고 있으므로 대칭 키 알고리즘
- 현실에서는 소인수분해로.
- 제3자 사기와 유사한 형태의 문제점 발생 가능
- 비대칭 암호화 알고리즘 (공개 키 암호화 알고리즘)
- 개인 키로 공개 키를 만듦. >> 공개 키는 공개되어도 상관없음
- 누군가가 공개 키로 암호화함. 복호화는 공개 키를 만든 사람만이 가능!
- TLS handshaking
- 대칭, 비대칭 알고리즘 둘 다 씀
- 키 교환 자체를 공개 키 알고리즘(비대칭)으로 함. (제 3자 사기가 일어날 수 있으므로)
- 연결이 생긴 이후에는 대칭 알고리즘으로 진행.
실습: 인증서 만들기
Wireshark 이용
openssl이라는 오픈소스 라이브러리
개인 키: 상위 인증 기관만 갖고 있음
공개 키로 상위 인증 기관에서 유효성 검증 가능
(ex. upbit의 인증서가 - 인증 기관에서 발급된 게 맞는지, 공개 키로 식별 가능)

암호화된 데이터로 전송 (https)

암호화되지 않고 내용이 그대로 보임 (http)

3. jQuery
크로스 브라우징
각 브라우저별로 지원하는 코드가 다르기 때문에 이중으로 코드를 작성해야 했음.
-> 개발자 고통 !!
jQuery
브라우저별 코드 차이를 하나의 API로 통일해줌. (지금은 jQuery 쓰진 않음)
브라우저별 차이를 개발자가 직접 처리하지 않도록 추상화.
모던 개발환경에서는 jQuery 안 쓰는 이유?
- 브라우저별 코드 양식을 통일했기 때문. (JS는 ECMAScript 표준을 따름)
- 이미 표준화되었기 때문에 jQuery의 조건분기가 오히려 오버헤드 유발
- (그러나 크로스 브라우징이 완전히 없어진 건 아님! 일부 남아있음. )
- react
- (이렇게 쓰면 이렇게 나올거임~~ (선언형))
- 코드 쓸 때 JS 저수준의 코드를 쓰지 않음
- react 문법으로 작성. (가상 DOM~~ shadow DOM ~~ )