mongoose 모듈이란?
데이터베이스를 테이블이나 엑셀처럼 쉽게 다룰 수 있도록 하는 모듈이다.
특히 몽고 db에는 없는 'Schema(스키마)'를 가지고 있기 때문에 몽구스 모듈을 통해
몽고 db에 넣어서 관계형 db처럼 사용할 수 있다.
Schema란?
관계형 데이터베이스처럼 조회 조건을 공통적으로 적용하도록
정해진 규칙으로 문서를 저장하게 하는 것이 스키마이다.
예를 들면 String, Number, Boolean 등 데이터 타입을 의미한다.
어떤 문서에는 name이 있고 또 다른 문서에는 name이 없을 수도 있기 때문에 일정한 조건으로 적용이 어렵다.
이에 따라 스키마로 수월하게 가능하다.
몽구스 모듈 설치
npm install mongoose --save
먼저 cmd창에 위의 내용을 입력하여 몽구스 모듈을 설치해준다.
밑의 예제는 몽고 db가 설치되었다는 것을 가정 하에 진행하겠다.
(몽고 db 설치 등에 관련해서는 추가적으로 글을 올릴 예정이다!)
회원가입 및 로그인을 할 수 있는
예제를 살펴보겠다.
사용 모듈 세팅 및 예제 변수 선언
require("dotenv").config();
var express = require("express");
var http = require("http");
var path = require("path");
var serveStatic = require("serve-static");
var expressErrorHandler = require("express-error-handler");
var expressSession = require("express-session");
var mongoose = require("mongoose");
var database;
var UserSchema;
var UserModel;
예제에서 사용하기 위한 모듈들을 먼저 등록해준다.
추가로 몽구스 모듈까지 입력한다.
몽고 db는 모듈에 등록하지 않아도 몽구스 모듈을 입력함으로써 가능해진다.
또한 각각 데이터베이스 객체, 스키마, 모델을 위한 변수를 선언하였다.
데이터베이스 연결
function connectDB(){
var databaseUrl = "mongodb://localhost:27017/shopping";
mongoose.connect(databaseUrl);
database = mongoose.connection;
database.on("open",function(){
console.log("데이터베이스가 연결되었습니다: " + databaseUrl);
UserSchema = mongoose.Schema({
id:String,
name:String,
pwd:String
});
console.log("UserSchema 정의함.");
UserModel = mongoose.model("users",UserSchema)
console.log("UserModel 정의함.");
});
database.on("error",console.error.bind(console,"몽구스 연결 에러..."));
database.on("disconnected",function(){
console.log("DB연결이 끊겼습니다. 5초 후 재연결 합니다.");
setInterval(connectDB(),5000);
});
}
var app = express();
app.set("port",process.env.PORT||3000);
app.use(express.urlencoded({extended:false}));
app.use("/public",serveStatic(path.join(__dirname,"public")));
app.use(expressSession({
secret:"my Key",
resave:true,
saveUninitialized:true
}));
- 데이터베이스 연결
먼저 db 연결을 위해 연결 정보를 가져온다.
기본 포트번호는 27017로 설정하였으며 shopping이라는 데이터베이스를 만들었기에 입력해주고
데이터베이스 연결을 해준다.
- Schema, Model 정의
내장 이벤트 open에서 스미카와 모델을 정의해준다.
데이터베이스 연결이 잘 됐는지 확인용으로 콘솔창에 띄워준다.
스키마 정의의 경우, 위에서 입력한 변수 UserSchema에 담았다. 스키마는 문서(=컬럼) 규칙을 정한 것이다.
id, name, pwd는 모두 String타입으로 지정했다.
모델은 어떤 컬렉션(=테이블)에 스키마를 담을지 설정해준다.
users라는 컬렉션에 지정한 UserSchema를 담기 위해 입력해주었다.
error 이벤트의 경우, function으로 넣지 않고 바로 입력하였다.
dicsonnected는 db 연결이 끊어졌을 때 나오도록 하며
setInterval는 정해진 시간마다 반복을 작업하도록 하며, 따라서 메소드로 5초마다 db 연결하도록 입력했다.
- 익스프레스 객체 생성
익스프레스 객체 생성은 지난 블로그글에서 작성했으니 내용을 생략하겠다.
Express 관련한 내용은 참고하면 좋을 것 같다.
회원가입 및 로그인 실행 함수
var addUser = function(database,id,pwd,name,callback){
console.log("addUser 함수 호출..");
var users = new UserModel({"id":id,"pwd":pwd,"name":name});
users.save(function(err,result){
if(err){
callback(err,null);
return;
}
if(result){
console.log("사용자 추가..");
}else{
console.log("사용자 추가 실패..");
}
callback(null,result);
});
};
var authUser = function(database,id,pwd,callback){
console.log("authUser 함수 호출..");
UserModel.find({"id":id,"pwd":pwd},function (err,result){
if(err){
callback(err,null);
return;
}
if(result.length>0){
callback(null,result);
}else{
console.log("일치하는 데이터가 없습니다.");
callback(null,null);
}
});
}
로그인과 회원가입 데이터를 다룰 함수이다. 함수는 이후 라우터에서 호출하여 사용하게 된다.
- 사용자를 추가하는 함수 (addUser)
users라는 변수에 new를 통해 UserModel 즉, 컬렉션을 정의한다.
save는 객체의 데이터를 저장하는 것이며 결과는 콜백 함수로 전달된다.
따라서 err 또는 result의 유무에 따라 결과가 나뉜다.
- 사용자를 인증하는 함수 (authUser)
로그인을 하기 위해 아이디와 비밀번호를 검색하도록 한다.
사용자 추가 함수의 users는 맨 위에서 모델 정의할 때 UserModel로 들어갔으니 users가 아닌 UserModel이다.
따라서 find에 id와 pwd를 가져오도록 했고
result의 length가 0보다 크다는 것은 데이터가 있을 경우이다.
에러는 없으니 콜백 함수에 null을 주고 result를 넘겼다.
라우팅 객체 생성
- 회원가입 경로
var router = express.Router();
router.route("/process/addUser").post(function(req,res){
console.log("/process/addUser 호출..");
var id = req.body.id;
var pwd = req.body.pwd;
var name = req.body.name;
if(database){
addUser(database, id, pwd, name, function(err,result){
if(err) {throw err;}
if(result){
res.writeHead("200",{"Content-type":"text/html;charset=utf-8"});
res.write("<h1>사용자 추가 성공</h1>");
res.end();
}else{
res.writeHead("200",{"Content-type":"text/html;charset=utf-8"});
res.write("<h1>사용자 추가 실패</h1>");
res.end();
}
});
}else{
res.writeHead("200",{"Content-type":"text/html;charset=utf-8"});
res.write("<h1>데이터베이스 연결 실패</h1>");
res.write("<div>데이터베이스를 연결하지 못했습니다.</div>");
res.end();
}
});
express.Router()로 라우팅 객체를 생성하였다.
데이터를 받아 웹페이지에 출력할 내용들을 입력해줄 것이다.
경로에 회원가입 링크가 올 때 req.body로 데이터들을 받아주고
database가 있을 때 if문을 실행한다.
만들었던 addUser 함수를 호출하여 사용한다.
result 유무에 따라 클라이언트에 응답할 웹페이지 출력 내용이 달라진다.
마지막에는 database 유무이다.
- 로그인 경로
router.route("/process/login").post(function(req,res){
console.log("/process/login 호출..");
var id = req.body.id;
var pwd = req.body.pwd;
if(database){
authUser(database, id, pwd, function(err,result){
if(err) {throw err;}
if(result){
var userName = result[0].name;
res.writeHead("200",{"Content-type":"text/html;charset=utf-8"});
res.write("<h1>로그인 성공</h1>");
res.write("<div>아이디: " + id + "</div>");
res.write("<div>이름: " + userName + "</div>");
res.write("<br/><br/><a href='/public/login.html'>다시 로그인</a>");
res.end();
}else{
res.writeHead("200",{"Content-type":"text/html;charset=utf-8"});
res.write("<h1>로그인 실패</h1>");
res.write("<div>아이디 또는 패스워드를 확인하세요</div>");
res.write("<br/><br/><a href='/public/login.html'>다시 로그인</a>");
res.end();
}
});
}else{
res.writeHead("200",{"Content-type":"text/html;charset=utf-8"});
res.write("<h1>데이터베이스 연결 실패</h1>");
res.write("<div>데이터베이스를 연결하지 못했습니다.</div>");
res.end();
}
});
app.use("/",router);
로그인 경로가 왔을 때 실행될 라우터이다.
마찬가지로 만들어 둔 authUser 함수를 호출한다.
userName는 매개변수로 가져온 id와 다르게 직접 가져와야 한다. 여러 데이터가 있을 수 있으므로 배열로 값을 가져왔다.
그리고 라우터 객체를 등록해주면 된다.
Express 서버 시작
var errorHandler = expressErrorHandler({
static: {
"404":"./public/404.html" }
});
app.use(expressErrorHandler.httpError(404));
app.use(errorHandler);
http.createServer(app).listen(app.get("port"),function(){
console.log("익스프레스 서버를 시작했습니다: " + app.get("port"));
connectDB();
});
에러 처리와 서버 시작 역시 지난 블로그 글에서 작성하였으니 참고 바란다.
에러의 경우 마지막에 입력해줘야 하는 점 주의하자.
4월 5일 수업 🌜
'개발 교육 TIL > back-end' 카테고리의 다른 글
[Node.js] Express 서버 연결, 데이터베이스, 라우터 - 파일 분리 (0) | 2022.04.12 |
---|---|
[Node.js] 비밀번호 암호화 - crypto, virtual함수, salt (2) | 2022.04.06 |
[Node] Express 설치&서버 연결 / post 데이터 및 오류페이지(404) 출력 (0) | 2022.04.04 |
[node] 내장모듈 - path, fs (0) | 2022.04.01 |
[Spring Boot] 스프링부트에서 JSP 사용하기 (0) | 2022.03.31 |