오늘은 express 모듈을 사용해 서버만들기 2탄으로 express와 미들웨어에 대해 작성해보려 한다!
미들웨어는 말 그대로 중간단계 역할을 하는 존재이다. 즉, 요청과 응답 사이에 express 자체에 있는 기능 외에 추가적인 기능을 넣어줄 수 있다.
express 자체 미들웨어를 사용해도 되고 다른 사람이만들어 놓은 미들웨어를 npm을 통해 다운받아 사용해도 된다.
'express 사용법에서 핵심은 '미들웨어'에 있다고 할 정도로 미들웨어는 express에서 중요한 역할을 한다.'
미들웨어는 app.use() 메서드를 통해 사용된다. app.set()과의 차이점은 app.set()은 전역으로 사용된다는 점이다.
예제1.
<미들웨어 사용법(1)>
1 const express = require('express');
2 const app = express();
3
4 app.get('/', (req, res, next) => {
5 res.send('Hello World');
6 next();
7 });
8
9 const middleware = (req, res) => {
10 console.log("미들웨어 테스트");
11 };
12
13 app.use(middleware);
14
15 app.listen(8080);
미들웨어는 위에서 아래로 실행되기 때문에 순서가 중요하다!!
먼저 app.get('/')이 수행되고 res.send()가 끝나고 응답을 종료해버리기 때문에 next()를 이용해 다음 미들웨어로 넘어가야한다.
예제2.
<미들웨어 사용법(2)>
1 const express = require('express');
2 const app = express();
3
4 app.use(function(req, res, next){
5 console.log('Time:', Date.now());
6 next();
7 });
8
9 app.use('/user/:id', (req, res) => {
10 res.send('user 접속');
11 });
12
13 app.listen(8080);
<오류 처리를 위한 미들웨어 함수>
const express = require('express');
const app = express();
app.use(function(err, req, res, next){
console.error(err.stack);
res.status(500).send('error!!!!');
})
app.listen(3000);
express.static
static 파일?
이미지, css, 스크립트 파일과 같이 그 내용이 고정되어 있어 응답할 때 파일 내용 그대로를 보여주면 되는 파일을 말함.
예제 1.
//static 미들웨어 사용.js
const express = require('express');
const app = express();
app.set('port', process.env.PORT || 8080);
app.use(express.static(__dirname + '/public1'));
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index2.html')
});
app.listen(app.get('port'), () => {
console.log(app.get('port'), '번 포트에서 서버 실행 중..');
});
<!--static 미들웨어 사용.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>express로 웹 만들기</title>
</head>
<body>
<h1>express로 웹 만들기</h1>
<p>메인 페이지입니다.</p>
<img src = "./sample.jpg" width="70" height="100">
</body>
</html>
이러면 html 파일 내에 이미지 파일 경로에 public/을 따로 명시해주지 않아도 자동으로 서버에서 static 폴더에서 해당 파일 찾은 후 띄워줌
router
라우터도 일종의 미들웨어! 클라이언트로부터 요청이 왔을 때 서버에서 어떤 응답을 보내주어야 할지 결정해줌.
ex) 'localhost:8080/'요청이 들어왔으면 index.html을 보내!!', 'localhost:8080/join.html/'요청이 들어왔으면 join.html을 보내!!'라고 알려주는 역할을 한다.
express에서 router는 'app.get', 'app.post', 'app.use' 등 처럼 express 모듈을 담은 변수 뒤에 http 메서드가 붙은 것인데, 이를 이용해 요청이 들어오는 경로와 응답을 만들 수 있음.
.
.
<HTTP 요청 메서드의 종류와 내용>
종류 | 주소 | 응답 |
---|---|---|
GET | / | index.html 파일을 송신함 |
GET | /join | join.html 파일을 송신함 |
POST | /user | 사용자를 등록함 |
PUT | /user/user_id | user_id가진 사용자의 정보를 수정 |
DELETE | /user/user_id | user_id가진 사용자의 정보를 삭제 |
첫번째 파라미터로 넣어준 경로로 요청이 들어오면 두번째 파라미터의 미들웨어를 실행한다.
ex)
다음과 같은 코드가 있고 어떤 요청이 들어왔다면 어떤 응답을 하게 될까?app.get("/user/:id", function (req, res) { res.send("user id: " + req.params.id });
하나의 GET 메서드로 /user/1이라는 요청이 URI 요청이 들어왔다고 생각해보자. 이 요청에 대한 응답으로 req.params.id에 접근하여 얻은 고객의 아이디를 문자열로 보내게 된다.
예제 1.
const express = require('express');
const app = express();
app.set('port', process.env.PORT || 8080);
app.use(express.static(__dirname + '/public1'));
app.get('/', (req, res) => {
const output = `
<h2>exppress로 웹 만들기</h2><br>
<p>메인 페이지 입니다.</p><br>
<img src = "./sample.jpg" width="200px" height="100px"/>
`
res.send(output);
});
app.get('/user/:id', (req, res) => {
res.send(req.params.id + "님의 개인 페이지 입니다.")
});
app.listen(app.get('port'), () => {
console.log(app.get('port'), '번 포트에서 서버 실행 중');
})
localhost:8080/에 접속할 때와 localhost:8080/user/roadbook으로 접속했을 때 다른 html 화면을 띄워주는 예제!
morgan
morgan은 Logger API이다. morgan은 request와 response를 깔끔하게 포매팅해주어 콘솔에 로그를 찍는 역할을 한다.
호출된 router가 어떤 상태이고, 어떤 결과 값인지를 보여준다.
인자로 여러 옵션을 넣어줄 수 있고 옵션마다 보여주는 정보도 다르다. 주로 개발 시에는 'dev'옵션을 사용한다!!
예제 1.
const express = require('express');
const morgan = require('morgan');
const cookieParser = require('cookie-parser');
const session = require('express-session');
const app = express();
// 포트 설정
app.set('port', process.env.PORT || 8080);
// 공통 미들웨어
app.use(express.static(__dirname + '/public1'));
app.use(morgan('dev'));
app.use(cookieParser('secretmessage')); // 암호화된 쿠키를 사용하기 위한 임의의 문자 전송
app.use(session({
secret: 'secretmessage', //암호화
resave: false, //새로운 요청 시 세션에 변동 사항이 없어도 다시 저장할지 설정
saveUninitialized: true, //세션에 저장할 내용이 없어도 저장할지 설정
cookie: {
httpOnly: true //로그인 구현 시 필수 적용, 자바스크립트로 접근 할 수 없게 하는 기능
}
}));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// 라우팅 설정
app.get('/', (req, res) => {
if(req.session.name) {
const output = `
<h2>로그인한 사용자님</h2><br>
<p>${req.session.name}님 안녕하세요.</p><br>
`
res.send(output);
}else{
const output = `
<h2>로그인한 사용자님</h2><br>
<p>로그인 해주세요.</p><br>
`
res.send(output);
}
});
app.get('/login', (req, res) => {
console.log(req.session);
//세션 쿠키를 사용할 경우
req.session.name = '로드북';
res.end('Login OK');
});
app.get('/logout', (req, res) => {
res.clearCookie('connect.sid'); //세션 쿠키 삭제
res.end('Logout OK');
});
// 서버와 포트 연결
app.listen(app.get('port'), () => {
console.log(app.get('port'), '번 포트에서 서버 실행 중');
})
콘솔에 위와 같은 메시지가 뜨는건 morgan을 장착해주었기 때문!!
/login으로 접속하면 쿠키 세션을 사용해 req.sessionn.name이라는 값을 넣어 주었고, 브라우저를 닫을 때 까지 유효하다.
/logout을 접속하면 세션 쿠키를 삭제한다.
/ 페이지로 접속했을 때 req.session.name 값이 있으면 다음 화면이 나온다!
req.session.name 값이 없다면 다음 화면이 나온다