실전 프로젝트 회고

 

프로젝트를 진행하면서 내게 제일 도전적인 기능은 채팅기능이였다.

다대다의 채팅 기능은 채팅의 제일 기본적인 기능이였기에 큰 문제 없이 연결되었다. 

하지만,

회원 비로그인시 또는 채팅방에서 나갔을 때 실시간으로 메세지알림을 주기 위해

해당 회원의 socket.id가 언제 생기고 언제 사라지는지를 직접 확인해봐야했다.

 

회원이 채팅방에 들어오면서 받는 socket.id는

브라우저를 새로고침하면 socket.id가 지속적으로 변경이 되었다. 

그래서 socket.id와 회원의.ID를 지속적으로 확인할 수 있게 db에 저장했고,

매번 채팅방에 들어올때마다 socket.id를 새로 고쳐줬다.

 

 

Websocket 과 socket.io를 정확이 구분을 못지었던 것같아 간략하게 이 둘의 차이점을 찾아보았다. 

Websocket 과 socket.io 차이점
Websocket은 양방향 소통을 위한 포로토콜이다.
프로토콜은 쉽게 말하자면, 서로 다른 컴퓨터끼리 소통하기 위한 약속 정도로 이해하면 된다.
 
반면, Socket.io는 양방향 통신을 하기위해 웹소켓 기술을 활용하는 라이브러리이다.
어찌보면 자바스크립트의 jQuery의 관계가 비슷하다고 할 수 있다. 그렇기 때문에 socket.io가 같은 기능을 구현하더라도 약간 느리지만, 많은 편의성을 제공한다. 또한, java, C++, Python 등 여러 언어들의 라이브러리 또한 지원한다.

 

Socket.io 라이브러리 안에 websocket이 있고,

socket.io 가 websocket보다 (지금은 많은 차이는 없지만) 호환이 잘 되기 때문에 잘 사용한 것같다.

 

Websocket
-      HTML5 웹 표준 기술
-      매우 빠르게 작동하며, 통신할 때 아주 적은 데이터를 이용함
-      이벤트를 단순히 듣고, 보내는 것만 가능함

Socket.io
-      표준 기술이 아니며, 라이브러리임
-      소켓 연결 실패 시, fallback을 통해 다른 방식으로 알아서 해당 클라이언트와 연결을 시도함
-      방 개념을 이용해 일부 클라이언트에게만 데이터를 전송하는 브로드캐스팅이 가능함

 

 

 

 

프로젝트 끝났으니깐, 말하는 아쉬운점.

하지만, 생각보다 더 많은 기능들을 도전하지 못했던 것이 너무 아쉽다.

프로젝트가 마무리되면서, 점점 서버에 대한 고민이 시작됬다.

 

'서버는 잘 작동이 되고 있는건가?'

'채팅을 사용하면 데이터가 미친듯이 쌓일텐데, 괜찮은건가?'

'사람들이 몰려와도 내 서버는 잘 버틸 수 있는가?'

'대체 어떻게 하면 그 결과를 볼수 있지?'

 

 

그 중 제일 아쉬운 것은 Nignx로 IP차단

 

배포를 시작하고 나니, 무자비하게 채팅을 하거나 테스트게시물을 올렸다. 그것 말고도 서버를 나쁜의도로 사용하기 위해 들어오기 때문에 IP차단이 필요하다고하여 IP차단을 염두해두고 있다.

Nginx로 IP 차단하려고 했지만, Nginx의 reverse port 가 적용이 안되서 사용된 포트라고 이슈를 뿜어내더니 결국에는 

'ERR_CONNECTION_REFUSED' 에러가 났다. SSL인증을 했는데도 나는 에러면 웹 시간이 맞지 않아서 나는 에러였다.

이 문제를 해결하려면 프론트분들한테 요청을 드려야했던 것같은데, 이것도 확실하지 않고 다음날의 최종 발표회에 준비하기 위해서 마무리를 지었다. 여러모로 이것저것 시도할 수 있는 시간들이 충분하지 않아 아쉬웠다.

 

 

 

어떤 개발자가 되고 싶은가

백엔드의 가장 큰매력은 결과를 수치로 볼 수 있는 것이 아닌가 싶다.

결과 값을 보기 위해서 그에 따른 엄청난 공부가 필요하겠지만

결과 확실히 있는, 데이터로 보는 개발자가 되고 싶다.

 

 

 

N빵

위치기반 공동구매 플랫폼 'N빵'입니다.<N빵>은 혼자사는 것보다 같이 구매하면 더 이득이라면?!
이웃과 함께 구매할 수 있는 공동구매 커뮤니티 서비스입니다.
자신의 주변에있는 공구 게시글을 작성해보고, 참여해 보세요:)더 좋은 서비스로 개선해나가기위해 피드백 이벤트를 진행중입니다.


많은 관심과 참여부탁드립니다!

 

5월 25일 ~ 6월 1일 (23시 59분)까지 공구게시글에 참여하시거나,
피드백을 작성해주신 분들에게는 추첨을 통해 치킨3마리와 메가커피 기프티콘 50잔을 빵빵 쏩니다!
당첨자 발표 및 상품 발송은 2022년 6월 2일 순차적으로 발송할 예정입니다

 

N빵 URL : https://nbbang.site

 

        Back-end(Node.js) : 장윤아, 오경은, 한재혁
        Front-end(React) : 권영민, 곽진호, 장수찬
        Designer(UI/UX) : 김원경, 이화정

 

웹 페이지와 모바일로도 확인가능합니다 :)

 

 

 

5주차 한일!

- 소켓/ CRUD 버그 수정 및 서비스배포

- 테스트 서버 연결

- 마켓팅, 유저피드백 반영

 

유저피드백 및 수정사항

1. 인터넷이 느릴 경우 글 등록하기를 여러번 누를 수 있는 현상이 있음

(게시글이 중복하여 생김)

2. 가격, 인원, 제목, 상세위치, 내용, 채팅 글자 수 제한

3. 설명페이지의 잘못된 이미지 변경

4. 비로그인 상태로 메인페이지 접근 시 바로 설명 페이지 보여주기

(설명페이지가 미흡하다는 의견이 있어 추가할 예정)

5. 게시물 카테고리 추가

6. 오른쪽 하단의 시/구/동 버튼을 누를 경우 해당 레벨에 맞게 화면 범위 설정

7. 채팅 유저리시트에서 외부를 클릭했을 경우 닫히게 설정

8. 브라우저 탭 상단의 배경이 흰색일 경우 로고가 보이지 않아, 색상 조정

9. 게시글이 없을 경우 생성되는 문구의 간격 조정

0. 채팅창에서 이용자가 이전 내용을 보고 있을 경우 새로운 메세지를 토스트메시지 형식으로 제공

11. 후기 서비스 (구현중)

12. 유저정보수정 (구현중)

13. 회원탈퇴 (구현중)

 

 

3주차 한 일!

3주차에는 실전프로젝트에 대해서 중간점검을 해야했다. 

우리가 최소 기능 구현하기로 했던 것들을 마무리하고 정리했다.

 

 

 

중간발표 시, (또는 인터뷰시) 알아두면 좋았을 것들.

- Websocket 과 socket io 의 차이점?

- 엔진엑스를 사용하는 이유는?

- HTTP 와 HTTPS 의 차이점? (HTTPS의 이점은?)

 

 

 

 

 

2주차에 한일!

완료된 로그인, 회원가입 API를 배포하여 프론트와 연결하는 작업을 했다. 

여유가 생겨 회원가입 인증코드 라이브러리(nodemailer)를 추가했다. 

회원가입을 하려면 인증코드가 필요하게 되서 번거롭게 됬다.

 

기획단계에서 socket관련 지식이 없으니 API를 추가한다거나 이벤트 이름을 설정하지 않았었다.

또한, mysql 에 채팅관련한 테이블을 추가했고, 소켓을 배포된 환경과 연결을 시켰다. 

 

메인페이지같은 경우, 프론트에 필요한 데이터를 지속적으로 추가되어

지속적으로 바뀌었다. 그만큼 Mysql을 쿼리문의 Inner Join, 새로운 group 생성하여 다시 적용했다.

 

Mysql 스케줄러를 통해서 1분마다 게시판 종료시점을 지난 경우, 완료된 상태로 자동화 시켰다.

또한, 이메일로 보내지는 인증코드는 DB에 저장되고 있어 5분마다 삭제되어 DB의 용량이 과부화 되지 않게 하였다.

 

 

 

2주차: 기술적인 이슈와 해결

이슈1. Mysql 에러, Error Code: 1071. Specified key was too long; 

Mysql에서 Primary Key(PK)를 여러개 설정 할 수 있다는 말에,

유저 고유번호, 이메일, 닉네임, 심지어 이미지까지 설정을 했다. 

 

하지만, 이미지같은 경우 Varchar(5000)으로 설정해둔 상태였다. 

총 PK의 문자길이가 제한이 되어있는데, 그 길이보다 더 길어져서 생긴 문제였다. 

이미지를 PK에서 제외하니, 해결되었다. 

 

 

 

 

4월 22일 금요일부터

드디어 나의 첫 항해 99 실전 프로젝트가 시작되었다!

 

이전 프로젝트와 다르게 6주를 진행하다보니,

프로젝트를 실제 사용되는 사이트처럼 좀더 디테일하게 구현해야할 것같다.

 

미래의 백엔드 개발자로서,

이번 프로젝트에서는 유지, 관리에 용이한 프로젝트로 만드는데 

좀더 집중해야할 것같다

 


1주차에 한일!

 

처음 기획한 사이트는 기부관련 웹사이트였다.

 

 결제시스템을 도전해보고 싶어서 기획하였는데,

"결제시스템이 되는지 안되는지 확인하라" 라는 멘토님 리뷰에

하지말라는 말인지 이해를 못하고... 3일동안 진짜 실현하는 방법만 찾아봤더랬다..

 

기획멘토링미팅에서 멘토님과 직접 이야기를 하고서는,

우리가 기획한 프로젝트가 개발자로서 보여줄 기능도 충분하지 않으며, 

실제 프로그램을 런칭한다고 가정했을때, 충분히 좋은 소재가 아님을 깨닭았다..... 

 

부랴부랴 두번째 프로젝트를 기획하고 개발을 시작했다. 

처음 기획했던 소재가 와이어프레임, API명세서 작성이 꽤 빨리 끝났기에 

Mysql DB연결도 하고, 쿼리로 직접 코드도 작성하기도 했었다.

 

그래서 두번째 기획된 주제가 확정되면서

하루만에 와이어프레임, API명세서, 디자인레이아웃까지 끝냈다. 

(배우지 않았던 기능을 시도한 기능들은 와이어프레임과 API명세서는 제외되었다.)

 

 나머지 2일은 로그인과 회원기능을 REST API 기능구현을 완료했고

해당 부분에 대해서는 https로 배포를 완료하였다. 

 

 

 

1주차: 기술적인 이슈과 해결!

 

이번 프로젝트에서는 웹사이트의 데이터 보안을 위해 HTTPS 를 사용하게 되었다. 

HTTPS란?
HTTPS는 하이퍼 텍스트 전송 프로토콜 보안(Hypertest Transfer Protocol Secure)의 약자이다. 
일반 HTTP 프로토콜은 서버에서부터 브라우저로 전송되는 정보가 암호화되지 않는 문제점이 있다. 그래서 터이터가 쉽게 도난당할 수 있다. HTTPS 는 SSL(보안 소켓 계층)을 사용하여 이 문제점을 해결했다. 

SSL은 서버와 브러우저 사이에 안전하게 암호화된 연결을 만들 수 있게 도와주고, 서버 브라우저가 민감한 정보를 주고받을때 이것이 도난 당하는 것을 막아준다. 데이터를 암호화하여, 도난을 당하더라도 암호화되어있기 때문에 해독할 수 없다. 

 

HTTPS 연결은 아래의 블로그를 참고하였습니다.

https://velog.io/@xkskxhtm96

 

 

 


 

 

이슈 1. crbug/1173575, non-JS module files deprecated.

<해결방법>

 

*윈도우 터미널(cmd) 아래와 같이 작성후, 컴퓨터 전원을 껏다가 켠다.

ipconfig/release

ipconfig/renew

ipconfig/flush DNS

 

 


 

 

해결되는가 싶더니, 깃배쉬에서 port 오류로 배포가 되지 않았다.

이슈 2. http에서 https로 포트포워딩이 안될때

 

 

<해결방법>

 

*깃배쉬에 작성, 모든 포트를 삭제하면된다.

1. 포트포워딩 확인하는 명령어 

sudo iptables -t nat -L --line-numbers

2. 포트포워딩 삭제 명령어 (갯수만큼 반복한다)

sudo iptables -t nat -D PREROUTING 1

3.  포트포워딩 확인하는 명령어 (삭제되었는지 확인한다.)

sudo iptables -t nat -L --line-numbers

 

 

 

아래의 블로그를 참고하였습니다.

https://kelly-tech.tistory.com/32

 

 

항해99 5주차에는 프론트엔드와 백엔드가 함께 미니프로젝트를 진행하게 되었다.

그전에도 CORS 모듈을 설치에 진행하는 것이 좋다라고만 들었는데, 

프론트 작업과 연결시 필요한 작업이기에 CORS를 자세히 알아보기로 했다.

 


 

CORS란?

 

CORS(Cross-Origin Resource Sharing), 교차 출처 리소스 공유라고 해석된다. 
CORS정책은 우리가 가져오는 리소스들이 안전한지 검사하는 관문이다. 

 

웹 개발을 하다보면 CORS 정책 위반으로 인해 에러가 발생한다. 콘솔에서 아래와 같은 메세지를 확인할수 있다.

 

CORS 관련 이슈는 모두 CORS 정책을 위반했기 때문에 발생한다.

위의 에러는 CORS를 허용해서 아무런 탈 없이 다른 출처 리소스를 공유해달라는 권고사항과 같은 것이다.

CORS라는 방어막 덕분에 우리가 이 곳 저 곳에서 가져오는 리소스가 안전하다는 최소한의 보장을 받을 수 있다.

 

 

 

출처 (Origin) 란?

 

서버의 위치를 의미하는 URL은 Protocol, Host, Port 까지를 의미한다. 

 

 

웹에는 SOP(Same Origin Policy) 와 CORS(Cross Origin Resource Sharing) 두가지 정책이 있다.

 

SOP(동일 출처 정책) ◀

같은 출처에서만 리소스를 공유할 수 있다" 라는 규칙을 가진 정책

 

→ URL의 구성요소 중 Protocol, Host, Port 세가지 동일한지 확인한다.

→ 같은 Protocol, Host, Port을 사용한다면 요소는 다르더라도 같은 출처로 인정된다.

→ 리소스가 자신의 출처와 다를경우, 브라우저는 교차출처 요청을 실행한다. 

즉, Protocol, Host, Port 중 하나라도 일치하지 않으면 Cross Origin 이라고 한다. 

 

실무에서 참고하자면

프론트 서버와 백엔드 서버 연결시

프론트 서버 URL이  http://localhost:3000,

백엔드 서버 http://localhost:8080 일때

 

SOP 정책에 어긋나기때문에, 서버로부터 응답이 넘어올 때 

브라우저에서 CORS 정책 오류를 발생시킨다. 

 

 

CORS (교차 출처 리소스 공유) ◀

추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 어플리케이션이 다른 출처의

선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에게  알려주는 체제이다. 

 

 

 

 

CORS 동작방식

 

1. 클라이언트에서  HTTP요청 헤더에 Origin을 담아 전달한다. 

 

2. 서버는 응답헤어에 Access-Control-Allow-Origin을 담아 클라이언트로 전달한다.

 

3. 클라이언트에서 자신이 보냈던 요청의 Origin과 서버가 보내준 Access-Control-Allow-Origin을 비교한다. 

자신이 보낸 Origin과 서버가 보내준 Access-Control-Allow-Origin을 비교하여 차단할지 말지 결정한다. 

만약 유효하지 않다면 그 응답을 사용하지 않고 버린다. 

(위의 경우 둘다 http://localhost:3000 이기 때문에 유효한 경우다.)

 

 

 

 

아래의 블로그를 참고하여 작성되었습니다.

https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-CORS-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95-%F0%9F%91%8F

 

[WEB] 📚 CORS 개념 💯 완벽 정리 & 해결 방법 👏

CORS(Cross Origin Resource Sharing) CORS 정책은 우리가 가져오는 리소스들이 안전한지 검사하는 관문이다. 웹개발을 하는 사람들은 이 CORS 정책위반으로 인해 에러가 나는 상황을 많이들 겪어봤을것이라

inpa.tistory.com

 

hanamon.kr에서 이미지참조

 

 

ORM이란?
ORM(Object Relational Mapping)은 객체와 관계와의 설정을 의미한다.

더 자세히 말하자면, 말하는 객체(Object)는 OOP (Object_Oriented Programming)의 객체로 구현되는 클래스와 RDB (Realational DataBase)에서 쓰는 데이터인 테이블을 자동을 연결하는 것을 의미한다. 클래스와 테이블은 서로 호환가능성을 두고 만들어진 것이 아니기때문에 일치하지 않는데, 이를 ORM을 통해 객체 간의 관계를 바탕으로 SQL문을 자동으로 생성하여 불일치를 해결한다. 

 

 

ORM의 장점

 

1. 객체 제향적인 코드로 인해 더 직관적이고 비즈니스 로직에 더 집중할 수 있게 도와준다. 

  • ORM을 이용하면 SQL문이 아닌 직관적인 코드로 데이터를 조작하여, 객체 지향 프로그래밍에 집중할 수 있다. 
  • 선언문, 할당, 종료 같은 부수적인 코드를 줄일 수 있다. 
  • 각종 객체에 대한 코드를 별도로 작성하여 가독성을 높일 수 있다.
  • SQL의 절차적이고 순차적인 접근으로 객체지향적 접근만 고려되어 생산성이 증가할 수 있다. 

 

2. 재사용, 유지보수, 리팩토링이 편리하다. 

  • ORM은 기존 객체와 독립적으로 작성되어 있어, 해당 객체들은 재활용 할 수 있다.
  • 매핑정보가 명확하여 ERD를 보는 의존도를 낮출 수 있다.

 

3. DRMS (DataBase Management System)에 대한 종속성이 줄어든다. 

  • 대부분 ORM솔루션은 DB에 종속적이지 않다. (구현방법과 많은 솔루션, 자료형 타입까지 종속적이지 않다.)
  • 개발자는 객체(Object)에 집중함으로서 극단적으로 DBMS를 교체하는 큰 작업에도 리스크가 적고 소요시간도 줄어든다. 
  • 자바에서 가공할 경우 equals, hashCode의 오버라이드 같은 기능을 이용할 수 있고 빠르게 가공할 수 있다.

 

 

ORM의 단점

 

1. ORM으로만 서비스를 구현하기 어렵다. 

  • 사용하기는 편리하지만, 설계는 매우 신중하게 해야한다. 
  • 프로젝트 복잡성이 커질 경우 난이도 또한 올라가며, 부족한 설계로 속도 저하나 일관성을 무너뜨리는 문제점이 생길 수 있다.

 

2. 절차가 많은 시스템에는 ORM의 객체 지향적인 장점을 활용하기 어렵다.

  • 절차가 많은 시스템에서는 다시 객체로 바꿔야하며, 그 과정에서 생산성 저하 또는 리스크가 많이 발생할 수 있다. 

 

 

ORM과 Node.js 프레임워크

ORM은 Node.js 추상화계층의 고려해야할 가장 높은 수준의 추상화이다. ORM의 요점처럼 관계형 데이터 베이스의 데이터를 애플리케이션의 객체에 매핑하는 것이다. Node.js ORM, Sequelize는 Postgres, MySQL, MariaDB, SQLite 등을 지원하는 Promize에 기반한 비동기로 동작한다.

 

 

 

 

아래의 블로그를 참고하여 작성되었습니다. 

https://yceffort.kr/2021/07/dont-use-nodjs-orm

 

Home

yceffort

yceffort.kr

 

Node.js 프로젝트를 

활성화시키면서 자동적으로 만들어지는

"package.json"

에 대해서 알아보고자 한다.


npm 이란?

 

npm은 Node Package Manager의 약어로, 명칭 그대로 노드 패키지 매니저이다.

 

노드가 자바스크립트 프로그램을 컴퓨터에서도 실행할 수 있게 해준다. 

자바스크립트 프로그램은 패키지로 npm에 등록되어 있으며

특정 기능의 패키지가 필요하다면 npm 에서 찾아 설치하면 된다.

 

 

 

package.json

프로젝트에 필요한 패키지를 추가하다보면 패키지가 어마어마해진다.
사용하는 패키지는 저마다 고유한 버전이 있으며,
동일한 버전을 설치하지 않으면 문제가 생길수 있다. 

이때 설치한 패키지의 버전을 관리하는 파일을
package.json 이라고 한다.

 

 

 

package.json 설치하기

프로젝트를 시작하기 전에 폴더 내부에 무조건 package.json부터 만들고 시작해야 한다!

npm init -y

* -y : 모든 항목에 Yes를 한다는 의미이다.

프로젝트 이름, 설명 등을 작성하고 싶다면, 

'npm init'로 실행시키고 콘솔창에서 작성할 수 있다.

 

 

아래의 형식으로 package.json 미리보기가 나온다.

{
  "name": "프로젝트 이름",
  "version": "프로젝트 버전",
  "description": "프로젝트 설명",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "작성자 이름",
  "license": "ISC",
  }
}

 

 

 

package.json 작성시 알아두기

package name :

패키지 이름으로 Package.json의 name 속성에 저장된다. 

 

version :

패키지 버전은 SemVer의 방식의 버전 넘버링을 따라 항상 세자리로 이루어져 있다. 

 

package.json에 가장 중요한 항목은 "name" 과 "version" 이다.

이 2가지 항목을 통해 패키지 고유성을 판별하게 된다.

필수 항목이며, 해당 내용이 없으면 패키지를 설치 할 수 없다.

 

 

description :

문자열로 기입해야하며, 

npm search로 검색된 리스트에 표시되어 만들어진 패키지를 찾고 이해하는 도움을 준다. 

 

entry point :

자바스크림트 실행파일 진입점. 보통 마지막으로 module.exports를 하는 파일을 지정한다. 

package.json의 main속성에 저장된다.

 

test commend

코드 테스트 시 입력하는 명령어를 의미한다.

package.json scripts 속성안의 test 속성에 저장된다.

 

git repository :

코드를 저장해둔 깃 저장소 주소를 의미한다.

소스에 문제가 생기면 사용자들이 이 저장소에 방문에 문제를 제기하거나

코드 수정본을 올릴 수 있다. package.json repository 속성에 저장된다.

 

keywords : 키워드를 문자열 배열로 설명되며,

npm search로 검색된 리스트에 표시되어 만들어진 패키지를 찾고 이해하는 도움을 준다.

 

bugs :

프로젝트의 이슈와 버그 트레킹을 볼수있는 url 또는 이슈를 알릴 email 주소를 입력한다. 

패키지 사용자가 문제가 있을 시 도움을 줄 수 있다.

 

 license

패키지 사용자들이 만들어진 패키지를 사용하기 위해 어떻게 권한을 얻고,

어떤 금기 사항이 있는지 이해하기 위해 라이센스를 명시해야 한다. 

 

dependencies :

패키지 설치시, 패키지 이름과 함께 설치된 버전이 저장된다.  

 

devDenpendencies :

패키지 모듈을 이용하는 사람이라면, 패키지 테스트 및 문서 작성에 사용되는

외부 프레임 워크는 다운로드를 원하지 않을 것이다. 

이러한 경우, devDependencies 객체에 디펜던시를 추가하는 것도 좋은 방법이다.  

 

 

 

 

더 자세한 사항은 아래의 링크를 참조할 수 있다.

https://docs.npmjs.com/cli/v8/configuring-npm/package-json

 

 

JavaScript에서 ES 란?

ECMASCRIPT의 약어를 뜻하며, 자바스크립트의 표준, 규격을 나타내는 용어이다.

 

모든 브라우저에서 동작할 수 있는 표준화된 자바스크립트가 필요해지면서

비영리 표준화 기구인 ECMA 인터네셔널에 자바스크립트의 표준화를 요청하였다.

 

ES5 는 2009년도에 HTML5와 함께 출연한 표준 사양이며,

ES6는 2015년에 버전업을하여 출시한 버전이다. 

ES6 이후로도 매년 업데이트가 되고 있고, 이후를 '모던 자바스크립트'라고 부른다.

 

아래에는 ES6에 포함된

let, const 키워드 /  화살표 함수 / 클래스 / 모듈 다루고 있다.

 

 


 

 

let, const 키워드

ES5

ES5의 변수 선언 방법은 var가 유일하다.

 

var :  선언과 초기화가 동시에 실행 

 

단점: 

함수 레벨 스코프 지원 → 지역변수를 전역변수로 사용남발

var키워드 생략 허용 → 암묵적 전역변수 양산

변수 중복 선언 허용 변수값의 의도치 않은 변경

변수 호이스팅  → 선언하기 이전에 참조

 

 

ES6

 var 키워드의 단점을 보완하기위해

let과 const 키워드가 도입되었다. 

 

const : 상수(변하지 않는 값, 재할당 x)

let : 재할당이 가능한 값

 

블록 레벨 스코프 지역변수{ } 에서 사용된 변수는 코드 블로내에서만 유효

변수 중복 선언 금지 →  중복 선언시, 문법에러가 발생

호이스팅 변수 선언 이전에는 참조할 수 없다. 

 

변수 선언에는 기본적으로 const를 사용하고, 

let은 재할당이 필요한 경웨 한정하여 사용하는 것이 좋다. 

 

전역 변수 (Global scope)
전역에서 선언된 변수이며, 어디에서든지 참조할 수 있다. 

지역 변수 (Local scope of Function-level scope)
지역(함수) 내에서 선언된 변수이며, 그 지역과 그지역의 하부지역에서만 참조할 수 있다.
함수 레벨 스코프 (Function-level scope) 
함수 내에서 선언된 변수는 함수 내에서만 유효, 함수 외부에서는 참조할 수 없다. 
즉, 함수 내부에서 선언변수는 지역변수 / 함수 외부에서 선언한 변수는 전역  변수

블록 레벨 스코프 (Block-level scope)
모든 코드 블록(함수 if문, for문, while문, try/catch 문 등)내에서 선언된 변수는 코드 불록 내에서만 유효, 
코드 블록 외부에서는 

 

 

 

화살표 함수(Arrow function)의 선언

 

화살표 함수는 function키워드 대신 (=>)를 사용하여 함수를 선언한다.

// 매개변수 지정 방법
    () => { ... } // 매개변수가 없을 경우
     x => { ... } // 매개변수가 한 개인 경우, 소괄호를 생략할 수 있다.
(x, y) => { ... } // 매개변수가 여러 개인 경우, 소괄호를 생략할 수 없다.

 

ES5보다  ES6의 화살표 함수는 좀더 간결하게 표현된다.

// ES5
var pow = function (x) { return x * x; };
console.log(pow(10)); // 100

// ES6
const pow = x => x * x;
console.log(pow(10)); // 100

기존의 함수와 this 바인딩이 다르며,

Lexical this를 지원하므로 콜백함수로 사용하기 편리하다.

(이 부분은 추가적으로 공부가 필요할 것같다.)

 

 

 

클래스(Class)

ES5

생성자 함수와 프로토타입, 클로저를 사용하여

객체 지향 프로그래밍을 구현하였다.

 

// ES5
var Person = (function () {
  // Constructor
  function Person(name) {
    this._name = name;
  }

  // public method
  Person.prototype.sayHi = function () {
    console.log('Hi! ' + this._name);
  };

  // return constructor
  return Person;
}());

var me = new Person('Lee');
me.sayHi(); // Hi! Lee.

console.log(me instanceof Person); // true

 

 

ES6

기존 방식보다 단순명료한 새로운 문법으로 Class함수가 추가 되었다.

 

// 클래스 선언문
class Person {
  // constructor(생성자)
  constructor(name) {
    this._name = name;
  }

  sayHi() {
    console.log(`Hi! ${this._name}`);
  }
}

// 인스턴스 생성
const me = new Person('Lee');
me.sayHi(); // Hi! Lee

console.log(me instanceof Person); // true

(디테일한 내용은 추가 공부가 필요할것같다.)

 

 

 

모듈 (Module)

모듈은 애플리케이션을 구성하는 개별적 요소로서 재사용이 가능한 코드 조각을 말한다. 

모듈은 세부 사항을 캡슐화하고 공개가 필요한 API만을 외부에 노출한다.

 

모듈은 파일단위로 분리되어 있으며 필요에 따라 모듈을 로드하여 재사용한다. 

 

script 태그에 type="module" 을 추가하면 모듈로서 동작한다. 

ES6 모듈의 파일 확장자는 모듈임을 명확하기 위해 mjs를 사용하도록 권장한다.

<script type="module" src="lib.mjs"></script>
<script type="module" src="app.mjs"></script>

 

모듈은 모듈 스코프를 가진다. 

모듈 내에서 var 키원드로 선언한 변수는 더이상 전역 변수가 아니며

window 객체 프로퍼디도 아니다.

// foo.mjs
var x = 'foo';

console.log(x); // foo
// 변수 x는 전역 변수가 아니며 window 객체의 프로퍼티도 아니다.
console.log(window.x); // undefined
// bar.mjs
// 변수 x는 foo.mjs에서 선언한 변수 x와 스코프가 다른 변수이다.
var x = 'bar';

console.log(x); // bar
// 변수 x는 전역 변수가 아니며 window 객체의 프로퍼티도 아니다.
console.log(window.x); // undefined
<!DOCTYPE html>
<html>
<body>
  <script type="module" src="foo.mjs"></script>
  <script type="module" src="bar.mjs"></script>
</body>
</html>

 

 

Export: 외부에 공개하여 다른 모듈들이 참조할 수 있게한다.

// lib.mjs
const pi = Math.PI;

function square(x) {
  return x * x;
}

class Person {
  constructor(name) {
    this.name = name;
  }
}

// 변수, 함수 클래스를 하나의 객체로 구성하여 공개
export { pi, square, Person };

 

 

Import: 모듈에서 공개한 (export)한 대상을 로드하려면 import 키워드를 사용한다.

아래의 import 3가지 방식을 참고할 수 있다.

// app.mjs
// 같은 폴더 내의 lib.mjs 모듈을 로드.
// lib.mjs 모듈이 export한 식별자로 import한다.
// ES6 모듈의 파일 확장자를 생략할 수 없다.
import { pi, square, Person } from './lib.mjs';                      // import 첫번째 방식
import * as lib from './lib.mjs';                                    // import 두번째 방식
import { pi as PI, square as sq, Person as P } from './lib.mjs';     // import 세번째 방식

console.log(pi);         // 3.141592653589793
console.log(square(10)); // 100
console.log(new Person('Lee')); // Person { name: 'Lee' }

 

 

<참고용>

lib.mjs / app.mjs / html 에서 import와 export 동작 사용방법 

// lib.mjs
export default x => x * x;
// app.mjs
// 브라우저 환경에서는 모듈의 파일 확장자를 생략할 수 없다.
// 모듈의 파일 확장자는 .mjs를 권장한다.
import square from './lib.mjs';

console.log(square(10)); // 100
<!DOCTYPE html>
<html>
<body>
  <script type="module" src="./lib.js"></script>
  <script type="module" src="./app.js"></script>
</body>
</html>

 

 

'오늘의 계절, 오늘의 노래' 라는 프로젝트를 진행하면서

JWT방식으로 로그인+회원가입을  프로그래밍을 해보았지만, 

JWT와 친해지지 않아 자세히 알아보기로 해보았다.

 


JWT 는 무엇일까?

JWT는 JSON Web Token의 약자로 전자 서명 된 URL-safe (URL로 이용할 수있는 문자 만 구성된)의 JSON입니다.

 

 

JWS (Jason Web Signature) : JSON을 암호화하여 URL-safe 문자열로 표현한 것

JWE (Jason Web Encryption) : JSON 데이터 구조를 사용하여 암호화 방법

*URL Safe : URL에 포함 할 수 없는 문자를 포함하지 않는 것

 

 

 

JWT 토큰 구성

JWT 토큰 구성은 헤어(header) + 페이로드(payload) + 서명(Signature)로 구성되며,

각 부분은  Base64로 인코딩 되어 표현된다. 

 

헤어(header) : 토큰의 유형 (JWT) +  HMAC, HS256(SHA256) 또는 RSA와 같은 해시 알고리즘을 나타낸다.

페이로드(payload) : 토큰에 담을 (name/value)를 한쌍으로 이룬 클레임(claim)정보를 나타낸다. 
                                   클레임 정보는 등록된 클레임, 공개 클레임, 비공개 클레임으로 나뉜다.

서명(Signature) : secret key를 포함하여 암호화 되어있다.

 

 

JWT Process 

- 클라이언트의 로그인 정보를 서버에 저장하지 않아, 토큰기반 인증 메커니즘을 제공한다.

- 로그아웃 시, 로컬 스토리지 저장된 JWT 데이터를 제거한다.

 

 

 JWT의 적용

  • 회원인증 : JWT의 가장 흔한 방법 
  • 정보교류 : 두 개체 사이에서 안정성있게 정보를 교환하기에 좋은 방법이다.  
                    정보가 서명되어있기 때문에, 보낸이가 바뀌진 않았는지 도중에 조작되지 않았는지 확인할 수 있다.

 

 

JWT 장점  

  • 사용자 인증에 필요한 모든 정보는 토큰 자체에 포함되어 별도 인증 저장소가 필요없다.
  • 디버깅 및 관리가 용이하다.
  • 트래픽 부담이 낮다.    
  • 독립적인 JWT

 

JWT 단점 

  • 더 많은 정보를 입력할수록 토큰이 커져 네트워크 부하를 줄 수 있다. 
  • JWT는 상태를 저장하지 않아 제어가 어렵다. 
  • 임의로 토큰을 삭제할 수 없어 '토큰 만료 시간'을 꼭 넣어주어야 한다.
  • Payload 는 암호화 한 것이 아니기 때문에
  • JWE를 암호화 하거나 Payload에 중요한 데잉터를 넣지 말아야한다.

 

 

 

 

opennaru blog, 'JWT(JSON Web Token) 이해와 활용' 참고하였습니다.

http://www.opennaru.com/opennaru-blog/jwt-json-web-token/

+ Recent posts