MEAN server.js
// server.js
// 모듈============================================
var express = require('express');
var app = express();
var path = require('path');
var bodyParser = require('body-parser');
var morgan = require('morgan');
var mongoose = require('mongoose');
var User = require('./app/models/user'); // 유저 DB 가져오기
var port = process.env.Port || 5000;
// 설정============================================
// 서버 공용 에셋 폴더를 설정한다.
app.use(express.static(__dirname + '/public'));
// index.html을 라우트 설정
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname + '/public/views/index.html'));
});
// body parser를 이용해서 POST 요청으로부터 정보를 가져온다.
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
// 앱 환경설정을 통해서 CORS 리퀘스트를 처리한다
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type, Authorization');
next();
});
// mongodb 데이터베이스 접속
mongoose.connect('mongodb://lemon:tester@ds045622.mongolab.com:45622/main');
// 모든 요청을 콘솔에 표시한다.
app.use(morgan('dev'));
// API 라우트
//====================================================
// 익스프레스 라우터 인스턴스를 가져옵니다.
var apiRouter = express.Router();
// 모든 리퀘스트를 사용하기위한 미들웨어
apiRouter.use(function(req, res, next) {
// 로그인하기
console.log('앱구동 성공');
next();
});
// 잘 돌아가고 있는지 라우트를 테스트한다.
// GET http://localhost:5000/api 에 접속한다.
apiRouter.get('/', function(req, res) {
res.json({
message: 'Start API Test'
});
});
// 끝에 /users 루트가 올 때
// =======================================
apiRouter.route('/users')
// 유저를 생성한다 (http://localhost:5000/user 에 접속해서 POST)
.post(function(req, res) {
// User Model 보기를 새로 생성한다.
var user = new User();
// 유저들의 이름을 설정한다. (리퀘스트로부터)
user.name = req.body.name;
// 유저들의 username을 설정한다. (리퀘스트로부터)
user.username = req.body.username;
// 유저들의 password를 설정한다. (리퀘스트로부터)
user.password = req.body.password;
user.save(function(err) {
if(err) {
// 순서를 복제한다.
if(err.code == 11000)
return res.json({
success: false,
message: '이미 있는 이름입니다.'
});
else
return res.send(err);
}
res.json({
message: '만들어졌습니다!'
});
});
})
// 모든 유저를 가져온다 (http://localhost:5000/qpi/user 를 통해 접속)
.get(function(req, res) {
User.find(function(err, users) {
if(err) return res.send(err);
res.json(users);
});
});
// /users/:user_id 가 끝에 올 때의 루트
//=========================================================
apiRouter.route('/users/:user_id')
// id에 해당하는 유저를 GET
.get(function(req, res) {
User.findById(req.params.user_id, function(err, user) {
if(err) return res.send(err);
// 해당 유저를 리턴
res.json(user);
});
})
.put(function(req, res) {
User.findById(req.params.user_id, function(err, user) {
if(err) return res.send(err);
// 요청이 있을 경우 새로운 유저 정보를 세팅한다
if(req.body.name) user.name = req.body.name;
if(req.body.username) user.username = req.body.username;
if(req.body.password) user.password = req.body.password;
// 유저를 저장한다
user.save(function(err) {
if(err) return res.send(err);
res.json({
message: '유저 업데이트!'
});
});
});
})
// 해당 id 인 유저를 삭제한다.
.delete(function(req, res) {
User.remove({
_id: req.parmas.user_id
},
function(err, user) {
if(err) return res.send(err);
res.json({
message: '삭제 완료'
});
});
});
// 라우트 등록
// '/api'기준으로 라우트
app.use('/api', apiRouter);
// 서버 시작
app.listen(port);
console.log('Start Server http://localhost:' + port);
// app/routes.js
// 방금 만든 모델을 불러온다.
var Nerd = require('./models/nerd');
module.exports = function(app) {
// 서버 라우트 ======================================================
// api call 같은것들을 조정한다
// 인증 라우트
// 샘플 api 라우트
app.get('/api/nerds', function(req, res) {
// 너드의 모든 데이터베이스를 Mongoose 를 사용하여 가져온다.
Nerd.find(function(err, nerds) {
// 에러가 있으면, 에러를 출력한다.
// 아무것도 없으면 res.send(err) 다음을 실행한다.
if(err)
res.send(err);
res.json(nerds); // 모든 nerds JSON 포맷으로 리턴한다.
});
});
// 만드는 것들을 조종하는 라우트를 지정한다. (app.post)
// 삭제하는 것들을 조종하는 라우트를 지정한다. (app.delete)
// 프론트엔드 라우트 ===================================================
// 모든 앵귤러 요청을 조종하는 라우트를 지정한다.
app.get('*', function(req, res) {
res.sendfile('./public/views/index.html'); // public/index.html 파일을 불러온다.
});
};
// app/models/db.js
// 몽구스 모듈을 끌어온다
var mongoose = require('mongoose');
// 너드 모델을 정의
// module.exports는 다른 파일들을 불러 올 때 파일을 통과시키도록 허용한다.
module.exports = mongoose.model('Nerd', {
name: {
type: String,
default: ''
}
});
var User = require('../models/user'); // .. 마침표 두개는 상위폴더.
var jwt = require('jsonwebtoken');
var config = require('../../config');
// 토큰 생성을 위한 슈퍼 시크릿
var superSecret = config.secret;
module.exports = function(app, express) {
var apiRouter = express.Router();
// 유저 인증 라우트 (POST http://localhost:8080/api/authenticate)
apiRouter.post('/authenticate', function(req, res) {
console.log(req.body.username);
// 유저 찾기
User.findOne({
username: req.body.username
}).select('name username password').exec(function(err, user) {
if(err) throw err;
if(!user) {
res.json({
success: false,
message: '인증 실패. 유저를 찾을 수 없습니다'
});
} else if(user) {
// 암호가 맞는지 체크
var validPassword = user.comparePassword(req.body.password);
if(!validPassword) {
res.json({
success: false,
message: '인증 실패. 틀린 암호입니다'
});
} else {
// 유저 패스워드가 맞으면
// 토큰을 생성한다
var token = jwt.sign({
name: user.name,
username: user.username
},
superSecret, {
expiresInMinutes: 1440 // 24시간 안에 만료한다.
});
// JSON에 있는 토큰 정보를 포함해서 리턴합니다.
res.json({
success: true,
message: '토큰 완료!',
token: token
});
}
}
});
});
// 토큰 확인을 위한 루트 미들웨어
apiRouter.use(function(req, res, next) {
console.log('앱이 들어올거임');
var token = req.body.token || req.query.token ||
req.headers['x-access-token'];
// 디코드 토큰
if(token) {
jwt.verify(token, superSecret, function(err, decoded) {
if(err)
return res.json({
success: false,
message: '토큰 인증을 실패했습니다'
});
else
// 모든게 괜찮으면, 다른 라우트에 사용하기 위한 리퀘스트를 저장합니다.
req.decoded = decoded;
});
// 토큰이 없는 경우
// 403 Http 응답(access forbidden) 과 에러메시지를 보낸다
} else {
return res.status(403).send({
success: false,
message: '토큰이 제공되지 않았습니다.'
});
}
next(); // 멈추지 않고 다음 루트로 진행합니다.
});
// 잘 돌아가는지 루트를 체크합니다
// GET http://localhost:5000/api 접속
apiRouter.get('/', function(req, res) {
res.json({
message: 'api >> / 로 접속 성공'
});
});
// 끝에 /users 가 왔을 때 라우트
// ========================================
apiRouter.route('/users')
// 유저 생성 ( POST http://localost:5000/api/users 로 접속)
.post(function(req, res) {
var user = new User(); // 유저 모델을 위한 새 인스턴스를 만듭니다.
user.name = req.body.name; // name 세팅
user.username = req.body.username; // usersname 세팅
user.password = req.body.password; // password 세팅
user.save(function(err) {
if(err) {
// 엔트리 복제
if(err.code == 11000)
return res.json({
success: false,
message: '이미 유저이름을 사용중입니다.'
});
else return res.send(err);
}
// 메시지 리턴
res.json({
message: '유저 생성 완료!'
});
});
})
// 모든 유저를 GET 한다 (GET http://localhost:5000/api/users 접속)
.get(function(req, res) {
User.find(function(err, users) {
if(err) res.send(err);
// 유저 리턴
res.json(users);
});
});
// 끝에 /users/:user_id 가 왔을 때
//============================================
apiRouter.route('/users/:user_id')
.get(function(req, res) {
User.findById(req.params.user_id, function(err, user) {
if(err) res.send(err);
// 유저를 리턴
res.json(user);
});
})
// 해당 아이디의 유저를 업데이트한다.
.put(function(req, res) {
User.findById(req.params.user_id, function(err, user) {
if(err) res.send(err);
// 요청이 존재하면 새로운 유저 정보를 세팅한다.
if(req.body.name) user.name = req.body.name;
if(req.body.username) user.username = req.body.username;
if(req.body.password) user.password = req.body.password;
// 유저를 저장한다.
user.save(function(err) {
if(err) res.send(err);
res.json({
message: '유저 업데이트!'
});
});
});
})
.delete(function(req, res) {
User.remove({
_id: req.params.user_id
}, function(err, user) {
if(err) res.send(err);
res.json({
message: '삭제 완료'
});
});
});
return apiRouter;
}; // module.export 끝