책 Node.js 교과서 개정2판 조현영 지음
const express = require("express");
//express모듈을 app변수에 할당
const app = express();
//app.set("port", 포트);로 서버가 실행될 포트를 설정
//process.env 객체에 PORT속성이 있으면 그값을 쓰고 아니면 3000
//app.set(키,값)
app.set("port", process.env.PORT || 3000);
//app.get(주소,라우터)는 주소에 대한 get요청 올때 어떤 동작할지 적는부분
//현재GET /요청시 응답으로 Hello,Express를 전송.
//익스프레스에서는 res.write나 res.end대신 res.send를 사용하면 됨
app.get("/", (req, res) => {
res.send("Hello,Express");
});
//(GET요청 외에도 POST,PUT,PATCH,DELETE,OPTIONS에 대한 라우터를 위한 app.post,app.put~~메서드가 존재한다)
//listen은 http웹서버와 동일.포트연결하고 서버실행. 포트는 app.get('port')로 가져옴
app.listen(app.get("port"), () => {
console.log(app.get("port"), "번 포트에서 대기 중");
});
///단순 문자열 대신 HTML로 응답하고 싶다면 res.sendFile메서드 사용하면 됨
파일의 경로를 path모듈을 사용해서 지정해야함
const express = require("express");
const path = require("path");
const app = express();
app.set("port", process.env.PORT || 3000);
app.get("/", (req, res) => {
//res.send('Hello,Express');
res.sendFile(path.join(__dirname, "/index.html"));
});
app.listen(app.get("port"), () => {
console.log(app.get("port"), "번 포트에서 대기 중");
});
미들웨어도 해보기
////6.2 자주 사용하는 미들middle웨어
//미들웨어는 익스프레스의 핵심
//요청과 응답의 중간(미들middle)에 위치하여 미들웨어라 부름
//라우터와 에러 핸들러 또한 미들웨어의 일종
//미들웨어는 요청과 응답을 조작하여 기능을 추가하긷 하고 나쁜 요청을 걸러내기도함
//미들웨어는 app.use와함께 사용. >>>app.use(미들웨어)<<
//익스프레스 서버에 미들웨어를 연결해보자
const express = require("express");
//
const morgan = require("morgan");
const cookieParser = require("cookie-parser");
const session = require("express-session");
const dotenv = require("dotenv");
const path = require("path");
//
dotenv.config();
const app = express();
app.set("port", process.env.PORT || 3000);
//app.use에 매개변수가 req,res,next인 함수를 넣으면 됨
//미들웨어는 위에서 아래로 순서대로 실행되고 요청과 응답사이에 특별한 기능추가할수있음
//next라는 세번째 매개변수를 사용했는데 다음 미들웨어로 넘어가는 함수임
app.use(morgan("dev"));
app.use("/", express.static(path.join(__dirname, "public")));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser(process.env.COOKIE_SECRET));
app.use(
session({
resave: false,
saveUninitialized: false,
secret: process.env.COOKIE_SECRET,
cookie: {
httpOnly: true,
secure: false,
},
name: "session-cookie",
})
);
//
app.use((req, res, next) => {
console.log("모든 요청에 다 실행됩니다.");
next();
});
//현재app.get 라우터에 미들워에 두개 연결되어있음 이때도 next호출해야 다음 미들웨어로 넘어감
app.get(
"/",
(req, res, next) => {
console.log("GET / 요청에서만 실행됩니다.");
next();
},
(req, res) => {
throw new Error("에러는 에러 처리 미들웨어로 갑니다.");
}
);
//에러처리미들웨어는 매개변수가 err, req, res, next로 네개야
app.use((err, req, res, next) => {
console.error(err);
res.status(500).send(err.message);
});
app.listen(app.get("port"), () => {
console.log(app.get("port"), "번 포트에서 대기 중");
});
(솔직히 아직 이해는 잘 안되는데 설명 적어놓기)
dotenv 패캐지는 .env 파일을 읽어서 process.env로 만든다.
dotenv 패키지의 이름이 dot(점)+env인 이유다. process.env.COOKIE_SECRET에 cookiesecret 값이 할당된다.
키=값 형식으로 추가하면 된다. process.env를 별도의 파일로 관리하는 이유는 보안과 설정의 편의성 때문.
비밀 키들을 소스 코드에 그대로 적어두면 소스코드 유출 시 키도 유출됨. 따라서 .env 같은 별도의 파일에 비밀 키를 적어두고 dotenv 패키지로 비밀키를 로딩하는 방식으로 관리하곤함. .env 파일만 잘 관리하면 비밀키 지킬 수 있다.
내
터미널 이렇게 잘 뜸
(책에서 콘솔 이라는데 )
[HTTP 메서드] [주소] [HTTP 상태코드] [응답속도]-[응답 바이트]
를 의미함. 요청과 응답 한눈에 볼 수 있음
morgan 미들웨어 다음과같이 사용
app.use(morgan("dev"));
dev 이외에 combined, common, short, tiny 등을 넣을 수 있음
인수 바꾸면 로그 달라져~
static 미들웨어
정적인 파일들을 제공하는 라우터(클라이언트의 요청 경로(path)를 보고 이 요청을 처리할 수 있는 곳으로 기능을 전달해주는) 역할을 함.
다음과 같이 사용
app.use("요청경로", express.static("실제경로"));
우리가 쓴거~
app.use("/", express.static(path.join(__dirname, "public")));
함수의 니수로 정적 파일들이 담겨있는 폴더를 지정하면 된다. p237 이해안되면 책봐 미래의 나.
예로
특정폴더명/stylesheets/style.css 는
http://localhost:3000/stylesheets/style.css 로 접근할 수 있음
css, js,이미지 파일들을 특정폴더에 넣으면 브라우저에서 접근할 수 있게 됨~
서버의 폴더 경로와 요청 경로가 달라서 외부인이 서버구조 쉽게 파악할 수 없어 보안에 좋아~
또
정적 파일들을 알아서 제공해줘서 4.3절(p190쿠키와 세션이해하기)처럼 fs.readFile로 파일 직접 읽어서 전송할
필요 없음. 만약 요청 경로에 해당하는 파일이 없으면 알아서 내부적으로 next 포출함.
만약 파일을 발견했다면 다음 미들웨어는 실행되지 않음. 응답으로 파일 보내고 next를 호출하지 않으니까.
body-parser
요청의 본문에 있는 데이터를 해석해서 req.body객체로 만들어주는 미들웨어.
보통 폼 데이터나 AJAX 요청의 데이터를 처리함
단 멀티파트(이미지,동영상,파일) 데이터는 처리하지 못해서 뒤에 나오는 multer 모듈 사용하면 됨
body-parser 미들웨어 이렇게 씀
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
body-parser는 JSON과 URL-encoded 형식의 데이터 외에도
Raw(요청의 본문이 버퍼 데이터일때 해석하는 미들웨어),
Text(덱스트 데이터 일때 해석하는 미들웨어)
형식의 데이터를 추가로 해석할 수 있음
npm i body-parser
이거 적어서 깔고 아래꺼 추가함
//body-parser
const bodyParser = require("body-parser");
app.use(bodyParser.raw());
app.use(bodyParser.text());
JSON은 JSON 형식의 데이터 전달 방식이고 URL-encoded 는 주소형식으로 데이터를 보내는 방식.
폼 전송은 주로 후자 사용함.
urlencoded 메서드 보면 { extended: false } 라는 옵션이 들어있음
이 옵션이 false면 노드의 querystring 모듈을 사용해 쿼리 스트링을 해석하고 true면 qs 모듈을 사용해서 쿼리스트링을 해석한다........
4.2절에서 POST와 PUT 요청의 본문 전달 받으려면 req.on('data') 와 res.on('end') 로 스트림 사용해야 했지
하지만 body-parser을 사용하면 그럴 필요없어 내부적으로 스트림을 처리해 req.body에 추가한다.
cookie-parser
요청에 동봉된 쿠키를 해석해 req.cookies 객체로 만든다.
사용하는 법
app.use(cookieParser(비밀키));
해석된 쿠키들은 req.cookies 객체에 들어감예로 name=zerocho 쿠키를 보내면req.cookies는 {name:zerocho} 가 됨. 유효기간이 지난 쿠키는 알아서 걸러짐
쿠키는 클라이언트에서 위조하기 쉬워서 비밀키를 통해 만들어낸 서명을 쿠키 값 뒤에 붙임.서명 붙으면 쿠키가 name=zerocho.sign 과 같은 모양됨~서명된 쿠키는 req.cookies 대신 req.signedCookies 객체에 들어있음
cookie-parser가 쿠키 생성할 때 쓰이는 것은 아님!
쿠키 생성/제거 할때는
res.cookie(키, 값, 옵션)
res.clearCookie
메서드 사용해야함
옵션은 domain, expires,httpOnly,maxAge,path,secure 등있음
이렇게~
res.cookie("name", "zerocho", {
expires: new Date(Date.now() + 900000),
httpOnly: true,
secure: true,
});
res.clearCookie("name", "zerocho", { httpOnly: true, secure: true });
쿠키를 지우려면 키와 값, 옵션도 정확히 일치해야 지워짐
단 expires 나 maxAge옵션은 일치할 필요 없어
signed 옵션은 true로 설정하면 쿠키 뒤에 서명이 붙음
서명을 위한 비밀 키는 cookieParser 미들웨어에 인수로 넣은 process.env.COOKIE_SECRET가 됨
express-session
세션 관리용 미들웨어
로그인 등 세션 구현하거나 특정 사용자 위한 데이터를 임시저장해둘 때 유용
세션은 사용자 별로 req.session 객체 안에 유지된다.
app.use( session({
resave: false,
saveUninitialized: false,
secret: process.env.COOKIE_SECRET,
cookie: {
httpOnly: true,
secure: false,
},
name: "session-cookie",
})
);
express-session 은 인수로 세션에 대한 설정을 받는다.
resave는 요청이 올 때 세션에 수정 사항 생기지 않아도 세션을 다시 저장할지 설정하는 것
saveUninitialized 세션에 저장할 내역이 없더라도 처음부터 세션을 생성할지 설정하는 것
둘다 필요없어서 false로 한거야~
express-session은 세션 관리시 클라이언트에 쿠키를 보냄
4.3절에서 배운 세션 쿠키가 이거다 이말임 p240 여기서 보충설명 다시 읽어봐라..
미들웨어의 특성 활용하기
app.use((req,res,next)=>{
console.log('모든 요청에 다 실행됩니다.');
next();
})
미들웨어는 req,res,next를 매개변수로 가지는 함수로서
app.use
app.get
app.post
등으로 장착함
특정한 주소의 요청에만 미들웨어가 실행되게 하려면 첫 번째 인수로 주소를 넣으면 된다~
app.use(
morgan("dev"),
express.static("/", path.join(__dirname, "public")),
express.json(),
express.urlencoded({ extended: false }),
cookieParser(process.env.COOKIE_SECRET)
);
위처럼 동시에 여러 개의 미들웨어를 장착할 수도 있고 다음 미들웨어로 넘어가려면 next함수 호출해야함.
위 미들웨어들은 내부적으로 next 호출하고 있어서 연달아 쓸 수 있는거.
next 호출하지 않는 미들웨어는 res.send나 res.sendFile 등의 메서드로 응답 보내야함
express.static과 같은 미들웨어는 정적파일을 제공할때 next 대신 res.sendFile 메서도로 응답보낸다.
따라서 정적파일 제공하는 경우
express.json, express.urlencoded,cookieParser 미들웨어는 실행되지 않음
미들웨어 장착 순서에 따라 어떤 미들웨어는 실행되지 않을 수도 ㅇㅆ다느넉ㄹ 기억햊도오아
만약 next 도 호출하지 않고 응답도 보내지 않으면 클라이언트는 응답못받고 계속 기다리게 됨
app.use((req, res, next) => {
req.data = '데이터 넣기';
next();
},(req,res,next)=>{
console.log(req.data);//데이터 받기
next();
});
현재 요청이 처리되는 동안 req.data를 통해 미들웨어 간 데이터 공유할 수 있음
새로운 요청오면 req.data초기화됨 속성명이 꼭 data일 필요없지만 다른 미들웨어와 겹치지 않고 조심
app.set과의 차이 p244
app.set으로 익스프레스에서 데이터를 저장할 수 있다는 것을 배웠음 app.get 또는 req.app.get으로 어디서든지 데이터를 가져올 수 있음 하지만 app.set 사용안하고 req 객체에 데이터를 넣어서 다음 미들웨어로 전달해야하는 이유가 있다. app.set은 익스프레스에서 전역적으로 사용되므로 사용자 개개인의 값을 넣기에는 부적절하며 앱전체의 설정을 공유할 때 사용하면 됨
req객체는 요청을 보낸 사용자 개개인에게 귀속되므로 req객체를 통해 개인의 데이터를 전달하는 것이 좋다
multer
멀티파트 형식으로 업로드할 때 사용하는 미들웨어
https://expressjs.com/ko/guide/routing.html
Express 라우팅
라우팅 라우팅은 애플리케이션 엔드 포인트(URI)의 정의, 그리고 URI가 클라이언트 요청에 응답하는 방식을 말합니다. 라우팅에 대한 소개는 기본 라우팅을 참조하십시오. 다음 코드는 매우 기본
expressjs.com
'노드 node.js' 카테고리의 다른 글
GET POST차이(app.get) / res.send / value와 name 차이 (0) | 2021.09.17 |
---|---|
node.js 로그인 창 만들기(npm,express,cookie)/ 에러 해결 app crashed - waiting for file changes before starting... (0) | 2021.09.16 |
템플릿 엔진 Template Engine (0) | 2021.09.14 |
http랑 https 차이점 (0) | 2021.09.14 |
쿠키와 세션 차이점(쿠키생성,사용자식별,노출안되는 버전,세션) (0) | 2021.09.14 |