Node.JS + Express + mongoDB Tutorial SignUp 구현하기

인증 / 인가 튜토리얼 (1/3)

Jun
5 min readAug 16, 2020

본 글은 Node.JS + Express + MongoDB(Mongoose) 를 사용한 튜토리얼 입니다.

회원가입(Sign up) 구현하기

먼저 회원가입을 진행하기 위해서는 유저의 정보를 담을 데이터베이스를 구성해야 한다. 본래 MongoDB는 NoSQL 데이터베이스 이기 때문에, SQL 데이터베이스와는 달리 테이블의 스키마를 설계할 필요가 없다. MongoDB에서는 콜렉션이 존재하는데, 하나의 엑셀 sheet라고 보면된다. 엑셀파일에 하나하나씩 행이 증가 하듯이, 콜렉션 안에 도큐먼트 들이 쌓인다. 도큐먼트는 객체로 쌓이기 때문에, 객체의 형태(스키마) 에 대한 제약없이 어느 객체는 하나의 도큐먼트로 콜렉션에 넣을 수 있다. 하지만, 서로 전혀 상관이 없는 데이터를 엑셀의 하나의 엑셀 sheet 에 담지 않듯이, MongoDB를 사용해 개발할 때에도 콜렉션의 형태를 미리 정하고 개발하는 듯 하다.

Users 라는 콜렉션에는 회원들의 정보가 저장이 된다. 위에서 설명했듯, 하나의 도큐먼트는 유저 한명의 정보다. 이를 mongoose(MongoDB를 보다 더 직관적이고 쉽게 사용할 수 있도록 도와주는 library)를 사용해 회원정보를 담을 콜렉션의 형태(스키마)를 정의 한다.

간단한 애플리케이션이라고 가정하고, 회원의 필수정보에는

  1. email
  2. password
  3. name 정도가 있다.

이렇게 하나의 도큐먼트(객체)에 들어갈 정보들을 field 라고 한다. 이를 mongoose Schema 를 통해 정의하면 다음과 같다.

/models/user.js

  1. mongoose의 Schema 객체를 인스턴스화 한다. 이 안에는 콜렉션에 쌓일 도큐먼트(===객체) 에 대한 정의가 들어간다.
  2. key 값에는 우리가 객체를 사용할 때 처럼 똑같이 key 값을 적어주고 (password), value 에는 다시 한 번 객체를 적어주게 되는데 우리가 저장할 데이터에 대한 정보를 정의하는 것이라고 생각하면 편하다. 즉 password 라는 key값에 들어올 데이터는 문자열이고, 꼭 필요하다는 정의를 내리는 것이다.
  3. phone 같은 경우에는 데이터 타입이 문자열이지만, 데이터베이스 저장할 때 꼭 필요한 데이터는 아니며 따라서 default 값으로 0을 주어서 도큐먼트(객체)가 생성 될 때 기본값으로 들어가게 된다. 만약, phone 이라는 field에 값이 들어오게 되면 덮어 씌어진다.
  4. 우리가 생성한 mongoose Schema 객체를 model 메소드를 사용해서 collection 과 연결시켜 준다. 앞으로 NodeJS + Express 앱에서 User 라는 객체로 Users 라는 콜렉션에 데이터를 저장하고, 조회하는 등의 메소드를 사용할 수 있다.

/controllers/auth.js

Users (회원 정보를 담을 콜렉션)에 들어갈 User document(객체) 에 대한 스키마를 정의 했으니 이제 회원가입을 하는 로직을 설계 할 수 있다.

한 줄 한 줄 자세한 설명은 주석으로 달아놓았다.

일단 NodeJS + Express 앱은 미들웨어의 향연이다. 미들웨어란 말 그대로 요청이 들어와서 응답으로 나가기 전까지 거치는 모든 중간의 함수를 의미한다. 함수는 모듈로 치환 될 수 있고, 다른 파일에서 이 모듈을 불러다가 연결한다면 미들웨어로서의 역할을 하게 되는 것이다.

미들웨어 연결하기

우리가 위에서 작성한 /controllers/auth.js 라는 모듈안의 signUp 함수는 유저가 회원가입을 요청 할 때에만 실행되어야 하는 함수다. 그래야 유저의 request(요청) 을 처리(db에 저장하고) response(응답)을 보낼 수 있다. 이 떄 요청이 들어오는 길을 지정하는 것을 라우팅 이라고 한다. 쉽게 말해서, url 의 주소가 하나의 길이 되는 것이고, 길로 들어온 요청에 대한 처리를 한 후 응답을 보내면 된다. 위의 signUp 함수는 처리와 응답을 보내는 로직이 구현되어 있다. 처리라고 하면 body 에 들어온 데이터를 User 도큐먼트(객체)로 생성해서 데이터베이스에 저장하는 행위를 말하고, 그 후에 상태메시지와 함께 status code (201) 을 응답으로 보낸다.

이 모듈(함수)은 인증/인가와 관련된 함수이므로 홈페이지주소/auth 라는 길로 안내하면 좋을 것이다. 또한 회원가입을 하는 요청이므로 홈페이지주소/auth/signup 으로 보다 더 세부적으로 명시하는 것이 좋다. 왜냐하면 나중에 로그인(signIn) 기능을 구현할 것이기 때문이다. 라우팅은 어찌보면 길을 안내하는 것과 같고, 폴더 구조를 보다 더 명시적으로 알아차리기 위해 정리하는 과정과 같다.

위를 코드로 구현하면 다음과 같다.

/routes/auth.js

/routes/index.js

이와 같이 계속해서 모듈화를 하는 이유는 추후 추가될 다른 미들웨어와의 연결성을 고려한 것이다. 이렇게 처음부터 확장성을 생각하고 모듈을 설계하는 편이 좋다.

app.js

server.js

최종 폴더/파일 구조

.
├── app.js: express app 을 생성하고 라우터를 연결하는 코드가 담긴 파일
├── controllers
│ └── auth.js: 인증/인가와 관련된 미들웨어들이 작성되 있는 파일
├── models
│ └── user.js: Users 콜렉션에 담길 document(객체)의 형태(스키마)가 작성되어 있는 파일
├── routes
│ ├── auth.js: 홈페이지주소/auth 로 들어오는 요청을 처리하기 위한 길과 controllers에서 작성된 미들웨어를 연결시키는 코드가 있는 파일
│ └── index.js: 앱의 모든 라우팅을 한번에 처리 하기 위한 파일
└── server.js: 서버를 실행시키는 코드가 있는 파일

3 directories, 6 filess

--

--