이번 과제는 클라이언트와 서버 등의 웹 아키텍처를 구성하는 여러 스프린트의 출발점으로서, 여러분들의 동료들과 같이 채팅을 할 수 있는 chat application의 클라이언트 부분을 만들어 볼 것입니다. 서버는 이미 AWS에 구축/배포되어 있는 코드스테이츠 Chatterbox Server를 활용하게 됩니다. 여러분들은 fetch API를 활용하여, 서버에 메세지를 요청하고(GET), 메세지를 보내게(POST) 될 것입니다.
이번에 만들 클라이언트는 앞으로 여러 스프린트에서 다시 활용할 것이기 때문에, 유지 가능하고, 재사용 가능한 코드를 작성할 수 있도록 노력하시면 좋겠습니다.
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 공격을 위해서 우리는 DOM 엘리먼트의 textContent가 아닌 innerHTML 기능을 사용해볼 것입니다. 먼저 두 속성의 차이를 확인해볼까요?
따라서, 이미 여러분들이 renderMessage 메소드를 구현했을 때에, DOM의 textContent를 이용했다면, XSS 공격을 허용하기 위해 innerHTML로 바꿔줍시다. 그 후에, API 문서에서 제공되는 XSS 공격을 시도해보세요. textContent를 쓰지 않고 어떻게 XSS 공격을 막아낼 수 있을까요?
아래의 Advanced 컨텐츠들은 테스트 케이스가 작성되어 있지 않습니다.
roomname
을 지정할 수 있습니다. 또한 GET 요청의 파라미터를 이용해서 Room을 필터링할 수 있습니다. select box를 만들어서 방별로 구분해서 메시지 조회/생성을 시도해보세요.코드스테이츠에서 운영 중인 Chatterbox Server의 API 문서는 다음과 같습니다. 우리는 다음 문서를 읽고 서버의 리소스를 활용할 수 있어야 합니다.
http://3.36.72.17:3000
GET /{githubID}/messages
{githubID} 부분은, 각 개인의 아이디를 넣어주세요. 아래 예를 참고하세요.
GET /kimcoding/messages
추가적인 파라미터를 사용할 수 있습니다. 파라미터는 /kimcoding/messages?roomname=로비
와 같이 사용할 수 있습니다.
parameter | 형식 | 설명 | 필수 포함 여부 |
---|---|---|---|
roomname | 방 이름(문자열) | 특정 roomname만 조회 | 필수 아님 |
JSON 형식으로 응답이 옵니다.
[
{
"id": 1,
"username": "김코딩",
"text": "안녕하세요",
"roomname": "로비",
"date": "2021-07-28T03:54:21.134"
},
// 여러 개의 메시지
]
메시지에서 사용하는 속성은 다음과 같습니다.
parameter | 형식 | 설명 |
---|---|---|
id | 숫자 | 고유한 아이디 |
username | 문자열 | 사용자 이름 |
text | 문자열 | 본문 내용 |
roomname | 문자열 | 방 이름 |
date | 문자열 | 작성한 시간 |
POST /{githubID}/messages
{githubID} 부분은, 각 개인의 아이디를 넣어주세요. 메시지는 24시간마다 자동으로 리셋됩니다.
요청 본문엔 다음 내용을 반드시 포함해야 합니다.
application/json
parameter | 형식 | 설명 | 필수 포함 여부 |
---|---|---|---|
username | 문자열 | 사용자 이름 | 필수 |
text | 문자열 | 본문 내용 | 필수 |
roomname | 문자열 | 방 이름 | 필수 |
JSON 형식으로 응답이 옵니다.
{
"id": 5
}
id는 숫자 형식이며, 새로 생성된 메시지의 고유한 ID값입니다.
POST /{githubID}/malicious
요청 본문은 필요하지 않습니다.
성공시 JSON 형식으로 응답이 옵니다.
{
"message": "attack success!"
}
POST /{githubID}/clear
요청 본문은 필요하지 않습니다.
성공시 JSON 형식으로 응답이 옵니다.
{
"message": "message initialized!"
}
새로운 메시지를 추가하기 위해 보내야 하는 본문을 객체로 표현하면 다음과 같습니다.
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 요청을 보낼 수 있는 훌륭한 도구이지만, GET 요청을 보낼 때만 유용합니다. (주소창을 통해서 URL을 요청할 시, 기본적으로 GET 요청을 보냅니다) GET이 아닌 기타 다른 요청을 보내려면, 개발자 도구를 이용해 fetch를 이용한 JavaScript 코드를 작성해야만 하죠.
이러한 한계로, 브라우저가 아닌 다른 종류의 HTTP 요청을 테스트할 수 있는 다양한 도구들이 존재합니다. 많은 API들이 HTTP 프로토콜을 이용하므로, API 테스팅 도구라고도 부릅니다. 이러한 API 테스팅 도구는, 클라이언트 입장에서 서버 API를 테스트하거나, 애초에 처음부터 API를 만들 때에도 매우 유용합니다.
우리에게 이미 API 서버가 주어져 있는 경우를 먼저 생각해봅시다. HTTP에서는 API 서버의 endpoint가 URL로 주어집니다. 예를 들어, 다음과 같이 API 문서가 주어져 있다고 가정합시다.
GET /kimcoding/messages
추가적인 파라미터를 사용할 수 있습니다.
사실 GET 요청은 브라우저로도 충분히 테스트가 가능합니다. POST 요청은 GET 요청과 다르게 본문(body)를 포함하는 경우가 대부분입니다.
본문 설정은, 앞서 보았던 (4)번 - HTTP 요청 설정 화면 에서 설정이 가능합니다. POST를 사용하는 API 문서를 먼저 확인해봅시다.
POST /kimcoding/messages
요청 본문엔 다음 내용을 반드시 포함해야 합니다.
JSON 형식으로 응답이 옵니다.
{
"id": 5
}
id는 숫자 형식이며, 새로 생성된 메시지의 고유한 ID값입니다.
다음 화면을 참고하여 요청 본문을 보내봅시다.
여러분이 한번에 응답을 확인할 수 있다면 매우 기쁘겠지만, 대부분 그렇지 않을 수도 있습니다. 다음과 같은 상황이 발생할 수 있습니다.
보통은 서버가 요청에 대한 응답을 던져주지 않는 경우에는 요청이 끝나지 않습니다. 이는 서버의 문제입니다. (만일 여러분이 서버를 만들고 있는 중이라면, 응답 처리를 했는지 확인해보세요!) 결국 timeout이라고 응답이 오게 될 겁니다.
결과에 혹시 아무것도 나오지 않거나, 기대했던 값이 나오지 않나요? HTTP 응답 코드를 한번 확인해보세요!
이 그림처럼 우측 상단에 HTTP 응답 코드가 표시됩니다. 400 Bad Request
라고 되어 있는 것을 보니, 요청이 잘못되었나 보네요.
뭐라도 결과가 나오는 경우, 결과를 잘 읽어보세요. 문제 해결의 실마리를 찾을 수 있을거예요.
참고: 이번 시간에 CSRF는 다루지 않습니다
XSS 공격을 막기 위해서 정규표현식을 활용해 볼 수 있습니다.