Sprint - Chatterbox Client

조 은길·2022년 2월 3일
0

Sprint

목록 보기
17/19
post-thumbnail


이번 과제는 클라이언트와 서버 등의 웹 아키텍처를 구성하는 여러 스프린트의 출발점으로서, 여러분들의 동료들과 같이 채팅을 할 수 있는 chat application의 클라이언트 부분을 만들어 볼 것입니다. 서버는 이미 AWS에 구축/배포되어 있는 코드스테이츠 Chatterbox Server를 활용하게 됩니다. 여러분들은 fetch API를 활용하여, 서버에 메세지를 요청하고(GET), 메세지를 보내게(POST) 될 것입니다.

이번에 만들 클라이언트는 앞으로 여러 스프린트에서 다시 활용할 것이기 때문에, 유지 가능하고, 재사용 가능한 코드를 작성할 수 있도록 노력하시면 좋겠습니다.

Bare Minimum Requirements

  • Chatterbox Server API 문서를 이용해서 클라이언트를 만드세요.
  • 클라이언트는 서버로부터 받아온 메시지들을 보여 줄 수 있어야하고, 내가 작성한 메시지를 서버에 보낼 수 있어야 합니다.
  • 클라이언트가 테스트에 통과할 수 있도록 만드세요.
  • XSS 공격을 어떻게 막을 수 있는지 생각해보세요.

구현 및 테스트 통과

repository 내의 client/scripts/app.js 에서 코드 작업을 시작합니다. 실제로 작동하는 클라이언트를 구현하기 위해서는 client/index.html 파일을 수정하세요. app.js 파일은 Singleton 패턴으로 작성되어야 합니다. 어떻게 시작해야할지 모르겠다면 다음 코드를 참고하세요.

const app = {
  server: 'http://3.36.72.17:3000/kimcoding/messages',
  fetch: function() {
    // todo
  },
  send: function() {
    // todo
  }
}

테스트를 통과하기 위해서는 spec/chatterboxSpec.js 파일을 참고하세요. npm test를 실행해 테스트할 수 있습니다.

서버에 리소스를 요청 혹은 생성하기 위해서, 우리는 서버에 요구하는 양식에 맞추어서 데이터를 전송하고 요청해야 합니다.

Chatterbox Server API 문서가 서버의 요구사항입니다. 서버가 어떤 형태로 요청을 해주기를 원하는지 확인해보세요.

XSS 공격

XSS 공격을 위해서 우리는 DOM 엘리먼트의 textContent가 아닌 innerHTML 기능을 사용해볼 것입니다. 먼저 두 속성의 차이를 확인해볼까요?

따라서, 이미 여러분들이 renderMessage 메소드를 구현했을 때에, DOM의 textContent를 이용했다면, XSS 공격을 허용하기 위해 innerHTML로 바꿔줍시다. 그 후에, API 문서에서 제공되는 XSS 공격을 시도해보세요. textContent를 쓰지 않고 어떻게 XSS 공격을 막아낼 수 있을까요?

Advanced Challenges

아래의 Advanced 컨텐츠들은 테스트 케이스가 작성되어 있지 않습니다.

  • Room: 메시지를 보낼 때 roomname을 지정할 수 있습니다. 또한 GET 요청의 파라미터를 이용해서 Room을 필터링할 수 있습니다. select box를 만들어서 방별로 구분해서 메시지 조회/생성을 시도해보세요.
  • 서버에 어떤 새로운 메시지가 등록된 경우, 브라우저에서 새로고침을 하지 않더라도, 서버에서 계속 메시지를 받아오려면 어떻게 해야 할까요? 주기적으로 자동으로 새로운 메시지의 fetch가 이루어지도록 만들어보세요.

Chatterbox Server API 문서

코드스테이츠에서 운영 중인 Chatterbox Server의 API 문서는 다음과 같습니다. 우리는 다음 문서를 읽고 서버의 리소스를 활용할 수 있어야 합니다.

Endpoint

http://3.36.72.17:3000

1. 메시지 조회

Request

GET /{githubID}/messages

{githubID} 부분은, 각 개인의 아이디를 넣어주세요. 아래 예를 참고하세요.

GET /kimcoding/messages

추가적인 파라미터를 사용할 수 있습니다. 파라미터는 /kimcoding/messages?roomname=로비와 같이 사용할 수 있습니다.

parameter형식설명필수 포함 여부
roomname방 이름(문자열)특정 roomname만 조회필수 아님

Response

JSON 형식으로 응답이 옵니다.

[
  {
    "id": 1,
    "username": "김코딩",
    "text": "안녕하세요",
    "roomname": "로비",
    "date": "2021-07-28T03:54:21.134"
  },
  // 여러 개의 메시지
]

메시지에서 사용하는 속성은 다음과 같습니다.

parameter형식설명
id숫자고유한 아이디
username문자열사용자 이름
text문자열본문 내용
roomname문자열방 이름
date문자열작성한 시간

2. 메시지 추가

Request

POST /{githubID}/messages

{githubID} 부분은, 각 개인의 아이디를 넣어주세요. 메시지는 24시간마다 자동으로 리셋됩니다.

요청 본문엔 다음 내용을 반드시 포함해야 합니다.

  • 요청 형식: JSON
    • MIME 타입: application/json
parameter형식설명필수 포함 여부
username문자열사용자 이름필수
text문자열본문 내용필수
roomname문자열방 이름필수

Response

JSON 형식으로 응답이 옵니다.

{
  "id": 5
}

id는 숫자 형식이며, 새로 생성된 메시지의 고유한 ID값입니다.

3. XSS 공격 메세지 삽입

Request

POST /{githubID}/malicious

요청 본문은 필요하지 않습니다.

Response

성공시 JSON 형식으로 응답이 옵니다.

{
  "message": "attack success!"
}

4. 메세지 초기화

Request

POST /{githubID}/clear

요청 본문은 필요하지 않습니다.

Response

성공시 JSON 형식으로 응답이 옵니다.

{
  "message": "message initialized!"
}

힌트: fetch를 이용해 JavaScript에서 POST 요청을 보내는 방법

새로운 메시지를 추가하기 위해 보내야 하는 본문을 객체로 표현하면 다음과 같습니다.

let message = {
  username: '김코딩',
  text: '새 글을 써보겠습니다',
  roomname: '사랑방'
};

이제 fetch를 이용해서 POST 요청을 보낸 후, 응답을 처리해봅시다. 해당 내용은 MDN Using Fetch에 보다 자세한 설명이 나와 있습니다.


const serverURL = 'http://3.36.72.17:3000/kimcoding/messages';
fetch(serverURL, {
  method: 'POST',
  body: JSON.stringify(message), // stringify 과정이 반드시 필요합니다. 왜일까요?
  headers: {
    'Content-Type': 'application/json'
  },
})
.then(response => response.json())
.then(json => {
  console.log(json)
  console.log('새 글을 작성했습니다')
});

HTTP API 테스트 - Postman

HTTP API 테스팅 도구

브라우저는 서버에게 HTTP 요청을 보낼 수 있는 훌륭한 도구이지만, GET 요청을 보낼 때만 유용합니다. (주소창을 통해서 URL을 요청할 시, 기본적으로 GET 요청을 보냅니다) GET이 아닌 기타 다른 요청을 보내려면, 개발자 도구를 이용해 fetch를 이용한 JavaScript 코드를 작성해야만 하죠.

이러한 한계로, 브라우저가 아닌 다른 종류의 HTTP 요청을 테스트할 수 있는 다양한 도구들이 존재합니다. 많은 API들이 HTTP 프로토콜을 이용하므로, API 테스팅 도구라고도 부릅니다. 이러한 API 테스팅 도구는, 클라이언트 입장에서 서버 API를 테스트하거나, 애초에 처음부터 API를 만들 때에도 매우 유용합니다.

HTTP API 테스팅 도구 (CLI)

  • curl (대부분의 리눅스 환경에 내장되어 있어서 바로 사용 가능합니다)
  • wuzz

HTTP API 테스팅 도구 (GUI)

  • Postman
    여기서는 가장 사용하기 쉬운 Postman을 소개하겠습니다.

Postman 사용하기

우리에게 이미 API 서버가 주어져 있는 경우를 먼저 생각해봅시다. HTTP에서는 API 서버의 endpoint가 URL로 주어집니다. 예를 들어, 다음과 같이 API 문서가 주어져 있다고 가정합시다.

GET 요청하기

Endpoint

http://3.36.72.17:3000

메시지 조회

Request

GET /kimcoding/messages

추가적인 파라미터를 사용할 수 있습니다.

Postman 화면 보기


POST 요청하기

사실 GET 요청은 브라우저로도 충분히 테스트가 가능합니다. POST 요청은 GET 요청과 다르게 본문(body)를 포함하는 경우가 대부분입니다.

본문 설정은, 앞서 보았던 (4)번 - HTTP 요청 설정 화면 에서 설정이 가능합니다. POST를 사용하는 API 문서를 먼저 확인해봅시다.

Endpoint

http://3.36.72.17:3000

메시지 추가

Request

POST /kimcoding/messages

요청 본문엔 다음 내용을 반드시 포함해야 합니다.

Response

JSON 형식으로 응답이 옵니다.

{
  "id": 5
}

id는 숫자 형식이며, 새로 생성된 메시지의 고유한 ID값입니다.

다음 화면을 참고하여 요청 본문을 보내봅시다.

응답 살펴보기

여러분이 한번에 응답을 확인할 수 있다면 매우 기쁘겠지만, 대부분 그렇지 않을 수도 있습니다. 다음과 같은 상황이 발생할 수 있습니다.

Q. 요청이 끝나지 않아요!

보통은 서버가 요청에 대한 응답을 던져주지 않는 경우에는 요청이 끝나지 않습니다. 이는 서버의 문제입니다. (만일 여러분이 서버를 만들고 있는 중이라면, 응답 처리를 했는지 확인해보세요!) 결국 timeout이라고 응답이 오게 될 겁니다.

Q. 기대했던 응답이 오지 않아요!

결과에 혹시 아무것도 나오지 않거나, 기대했던 값이 나오지 않나요? HTTP 응답 코드를 한번 확인해보세요!


이 그림처럼 우측 상단에 HTTP 응답 코드가 표시됩니다. 400 Bad Request라고 되어 있는 것을 보니, 요청이 잘못되었나 보네요.

뭐라도 결과가 나오는 경우, 결과를 잘 읽어보세요. 문제 해결의 실마리를 찾을 수 있을거예요.


Browser Security

참고: 이번 시간에 CSRF는 다루지 않습니다

CORS

XSS

XSS 공격을 막기 위해서 정규표현식을 활용해 볼 수 있습니다.

RegEx Tutorial

RegEx Testing

js-security-best-practice

Preventing XSS

OWASP Cheat Sheet


해당 github 링크

profile
좋은 길로만 가는 "조은길"입니다😁

0개의 댓글