npde에서 웹 서버 프레임워크의 대표적인걸
말해보라 한다면 가장 먼저 나오는게
express 다
기존에 쓰던 메소드들 당연 쓸수있고
추가적으로 편리한 메서드들을 사용해 기능적으로도
보완이 된다
코드를 분리하기 쉽게 만들어 관리하기도 쉽다
그리고 중요한게. .
이제부터 웹 서버 만들어 뭔가를 할 수 있는 시작 지점에 와있다는것!
이번 단계를 끝마치게 되면 대충 앞서 배운 html css js 등을 활용해
UI를 만들어 볼 수도 있고
암튼 뭔가 웹 서비스 다운걸 만드려 할 수 있다!
시작!
npm init | |
![]() |
![]() |
npm i express | ![]() |
npm i -D nodemon | ![]() |
까지 설치를 했다면 하나 바꿔줘야 할 부분이 있다
바로 package.json의 scripts 속성 부분을
바꿔줘야 한다
https://whaledowny.tistory.com/38
8)Nodejs_ npm(패키지 메니져)_(1)
JS가 세상이 나오고 시간이 꽤 흘럿다 그리고 여러 JS 사용하는 개발자들이 생겨났고 그 사람들은 개발을 하며 모듈이라는걸 하나둘 만들어냈다 개발을 좀 더 쉽고 간편하게 하기 위해서 이 모듈
whaledowny.tistory.com
여기서 말 했었듯 start 로 명령어를 넣어두고 파일을 연결해 서버를 가동 시킬수 있다 했으니까..!
nodemon app을 해주게 되면
소스코드 바뀔 때 마다 자동으로
서버를 재시작 해서 app(서버가 될 JS임)을
다시 껏다 켤 필요 없게 해
그리고 저건 개발용으로만 써야지
배포때는 굳이 nodemon을 쓸 필욘 없다
....app을 만들고~
![]() |
![]() |
![]() |
![]() |
저기 scripts에 명령어 지정한 start를 콘솔에 쓰면
app.js 이라 만들어논 서버가 가동이 될거고
3000 번 포트로 이동이 되며
끝!
서버 열리는건 확인 했고. .
html 파일 만들고 fs 모듈 사용해서 저 서버에 연결해서 열어야지
![]() |
![]() |
![]() |
자자 숨은 그림 찾기~~
저거 저대로 실행하면 안열림...
에러나야 정상임..... 실제로 에러 났고 경로도 맞는데 안열리길래...
https://whaledowny.tistory.com/40
파일 경로 디렉토리 오류(만약 경로와 파일명이 맞는데 안된다면 의심해야 할게 있음 그건 바로.
와따마 히사시~부리부리부리 html 파일 만들어서 fs 모듈 사용해 연결 하고 서버 켰더만 에러가 떴다.. 지금 이 에러는 굉장히 흔한 오류로.. 지금 저 경로의 문제다... ... 라고 생각 했으나 보면 경
whaledowny.tistory.com
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
미들웨어
미들웨어란
서로 다른 애플리케이션이 서로 통신하는 데 사용되는 소프트웨어라 부른다
요청과 응답을 조작하기도 하고
나쁜 요청같은걸 걸러내기도 하며
에러가 났을시 그걸 잘 뒤처리 하기도 한다
![]() |
● app.use((req, res, next)) : 모든 요청에서 미들웨어 실행 ● app.use('/abc', (req, res, next)) : abc로 시작하는 요청에서 미들웨어 실행 ● app.get('/abc', (req, res, next)) : abc로 시작하는 GET요청에서 미들웨어 실행 여기서 next라는 세번째 매개변수는 다음 미들웨어로 넘어가기 위한 함수로 저거 호출안하면 안넘어감. |
지금은
![]() |
![]() |
저 두번째 app.get('/',(req, res, next)) 미들웨어에서 에러가 나고
그리고 그 밑에
app.use((err, req, res, next)) 에러처리 미들웨어로 넘어가 저게 나옴
에러처리 미들웨어는 저렇게 매개변수가 4개다
모든 매개변수를 안쓰더라도 매개변수는 꼭 4개여야만 한다.
첫번째 매개변수엔 에러에관한게 담기고
res.status() 메서드로 HTTP 상태 코드를 지정 할 수있음
기본 디폴트는 200
그리고 이 에러헨들러 같은 미들웨어는 별일없으면
코드 가장 아래에 위치하게 해놓자
미들웨어 통해 요청/응답 등 여러 기능 추가도 되는데
이걸 유용한 패키지로 이미 많들어 놨다
(이런거 뭐 막 새로 생기면 업뎃 할거. .)
npm i morgan cookie-parser express-session dotenv
dotenv 이건 process.env를 관리하기 위한건데
저거 빼곤 morgan, cookie-parser, express-session 까진 미들웨어다
저게 뭔지는
https://whaledowny.tistory.com/38
8)Nodejs_ npm(패키지 메니져)_(1)
JS가 세상이 나오고 시간이 꽤 흘럿다 그리고 여러 JS 사용하는 개발자들이 생겨났고 그 사람들은 개발을 하며 모듈이라는걸 하나둘 만들어냈다 개발을 좀 더 쉽고 간편하게 하기 위해서 이 모듈
whaledowny.tistory.com
요 있음. .
다음으로 해야 할건
app.js에 패키지 넣고
추가를 해줘야 한다
.env 파일을 만들어줘야 한다
![]() |
저기 cookiesecret 자리가 사실 이제 쿠키의 코드가 들어가며 깃으로 버전 관리 할때 저건 안올린다 |
![]() |
require()로 모듈들 가져오고. . 근데. . app.use() 여기에 그 왜 ![]() 이거 없음?? 저 미들웨어 안에 이미 다 들어가 있음.. dotenv 패키지가 하는건 .env 파일을 읽어 process.env로 만드는걸 함. 저기 process.env.COOKIE_SECRET 에 cookiesecret 값이 할당 되는거(key=value 형식으로 추가하면됨) ※ process.env를 따로 파일 만들어 관리 하는 이유는 보안과 관련 있음. .env에 별도로 관리하고 dotenv 패키지로 비밀 키를 로딩하는 방식으로 관리 한다. 소스코드 유출되도 저 파일만 잘 관리하면 보안의 위험은 덜한다 |
morgan
요청과 응답에 대한 정보를 콘솔에 기록 한다
그리고 morgan미들웨어는 이런식으로 쓴다
app.use(morgan('dev'));
morgan 미들웨어 인수 | ||
![]() |
dev | 개발환경에 사용 |
![]() |
combined | 배포환경에서 사용. 불특정 다수가 쓰기에 IP로그를 남김 |
![]() |
common | 배포환경에서 사용. |
![]() |
short | 기본 설정보다 짦은 로그와 시간을 출력함 |
![]() |
tiny | 최소화된 로그를 출력 |
static
정적인 파일들을 제공하는 라우터
express안에 있기때문에 굳이 따로 설치는 않함
app.use('필요경로', express.static('실제 경로'));
이런식으로 쓴다
함수의 인수로 정적 파일들이 담긴 폴더를 지정하면된다
현재는 public 폴더가 지정되있다
public?? 읎는디??
정적인 파일들이 뭐요?
CSS 파일이나 JS파일 이미지 파일 등등....
예를 들어 public/stylesheets/style.css 파일이 있다면
http://localhost:3000/stylesheets/style.css 로 접근이 가능하단거다
(저 public이 실 서버 경로엔 있지만 요청 주소엔 없다는점!)
이렇게 하면 좋은점이 서버의 폴더 경로와 요청 경로가 다르므로
외부인이 서버 구조를 쉽게 파악할 수 없다!! (보안에 좋다.)
fs.readFile() 써서 일일이 연결 할 필요 없다
만약! 내부 요청 경로에 해당 파일이 없다면?
내부적으로 알아서 next 호출함!
근데! 파일이 있다면 다음 미들웨어는 실행안됨.
(응답으로 파일 보내고 next 호출 안할거니까)
body-parser
요청 본문 데이터 읽어
req.body 객체로 만들어주는 미들웨어
폼 데이터나 AJAX 요청의 데이터를 처리함.
단, 영상, 사진, 파일 데이터는 처리 못함.
(multer 모듈 쓰면 가능함)
예전엔 body-parser를 설치 했으나
이제는 express 안에 내장되있어 그냥 쓰면됨.
JSON이나 URL-encoded 형식의 데이터 말고
Raw나 Text 형식의 데이터도 해석이 가능한데
그건 express안에 없어서 따로 설치 할 필요가 있긴 함
만약 버퍼나 텍스트 형식인 요청을 처리 할 경우엔 설치 해줘야함
![]() |
사용법은![]() 이렇게 쓰면됨. . |
- Raw : 요청 본문이 버퍼 데이터 일 때 |
- Text : 텍스트 데이터 일 때 |
- JSON : JSON형식 데이터 일 때 | { name: Downy, age: 20, }을 본문에 보내면 req.body에 그대로 드감.
- URL-encoded : 주소 형식 데이터 일 때 | name=Downy&age=20을 본문에 보내면 req.body에 { name: Downy, age: 20, } 가 들어감
저기 urlencoded 메서드에 { extended : false } 라고 했음
이게 false 면 node의 querystring 모듈을 사용해 쿼리스트링을 해석
이게 true 면 qs 모듈을 사용해 쿼리스트링을 해석
(qs 모듈은 npm 패키지며 querystring 모듈의 기능을 확장한 모듈임)
이 패키지가 내부적으로 스트림을 처리해 req.body에 추가함
스트림 처리를
https://whaledowny.tistory.com/35
6)Nodejs_http로 서버 만들기(2)_ Cookie and Session
클라이언트에서 보내는 요청의 단점은 누가 보낸지 알수 없음이다 요청을 보낸 PC의 IP는 찾을수 있어도 한 컴퓨터로 여럿이 쓴다면 그게 누가 요청 한건지 어찌앎? 로그인을 만들면 되잖음! 맞
whaledowny.tistory.com
res.on('data') | res.on('end') |
![]() |
![]() |
뭐 이런식으로 했으나
이젠 그럴 필요 읎다
cookie-parser
요청에 포함된 쿠키를 해석해 req.cookies 객체로 만든다
app.use(cookieParser(비밀키));
이렇게 사용함
비밀 키를 첫번째 인수로 넣어주고
서명된 쿠키일 경우 제공한 비밀 키를 통해
내 서버가 만든 쿠키임을 검증 할 수 있다
쿠키는 클라이언트가 위조하기 쉽다
그래서 비밀키를 통해 만들어낸 서명을 쿠키 값 뒤에 붙인다
(서명이 붙은 쿠키 : name=downy.sign 같은 모양임)
서명된 쿠키는 req.cookies 대신 signedCookies객체에 붙는다
cookie-parser은 쿠키를 생성 뿐 아니라 제거를 위해서도 쓰인다
res.cookie-parser, res.clearCookie 메서드를 써야 한다
res.cooie(key, value, option) 형식으로 사용한다
https://whaledowny.tistory.com/35
6)Nodejs_http로 서버 만들기(2)_ Cookie and Session
클라이언트에서 보내는 요청의 단점은 누가 보낸지 알수 없음이다 요청을 보낸 PC의 IP는 찾을수 있어도 한 컴퓨터로 여럿이 쓴다면 그게 누가 요청 한건지 어찌앎? 로그인을 만들면 되잖음! 맞
whaledowny.tistory.com
res.cookie('name', 'downy', {
expires: new Date(Date.now() + 100000),
httpOnly: true,
secure: true,
});
res.clearCookie('name', 'downy', { thhpOnly: true, secure: true });
쿠키를 지우려면?
key와 value 외에 option 도 정확히 일치 해야 지워진다.
(expires나 maxAge 까지 같을 필욘 읎음)
option 중 signed가 있는데 이걸 true로 설정할 시에 쿠키 뒤에 서명이 붙는다.
내 서버가 쿠키르 만들었다는걸 검증할 수 있기땜에
대부분 서명 옵션을 true로 켜두는 편이다.
서명을 위한 비밀 키는 cookieParser 미들웨어에 인수로 넣은
process.env.COOKIE_SECRET이 된다
저 COOKIE_SECRET의 비밀 키 번호는 dotenv 모듈로 관리하는
.env 파일 안에 있다
(임의로 cookieseret라 해뒀음)
express-session
세션 관리용 미들웨어다
로그인등 이유로 세션을 구현하거나
특정 유저를 위한 데이터를 임의 저장 해둘 때 유용함
express-session은 인수로 세션에 대한 설정을 받는다
resave 는 요청 들어 올 때 세션에 수정 사항이 생기지 않아도
세션을 재저장 할 지 설정하는거고
saveUninitialized 는 세션에 저장할게 없더라도
처음부터 세션을 생성 할 지 설정 하는거
express-session은 세션 관리 시 클라이언트로 쿠키를 보낸다
안전히 쿠키를 전송 하려면 쿠키에 서며을 추가 해야 되고,
쿠키 서명엔 secret 값이 필요 하다
(cookie-parser의 secret와 같게 설정 하는게 좋음)
세션쿠키명을 name 옵션으로 설정한다.
(기본 디폴트명은 connect.sid)
이 cookie 옵션은 세션 쿠키에 대한 설정이다
일반적인 쿠키 옵션 모두 제공됨
지금은 httpOnly를 true로 해서
클라이언트가쿠키 확인을 못하게 했음
secure는 false로 해서
https가 아닌 환경에서도 쓸수있게 했음.
배포땐 https를 적용해서 secure를 true로 바꿔놔야함.
https://whaledowny.tistory.com/36
7)Nodejs_http로 서버 만들기(3)_https, http2, cluster
https 모듈은 웹 서버에 SSL 암호화를 추가한것 GET, POST 요청을 할 때 오가는데이터를 암호화 하여 중간에 요청 데이터를 가로 채더라도 그 내용을 확인 못하게 만든다 이 SSL이 적용된 사이트는 저
whaledowny.tistory.com
store 라는 옵션은
현재 메모리에 세션을 저장하도록되 있는데
서버를 재시작해 초기화 되어 세션 모두 사라지더라도
store 에 DB를 연결해 세션을 유지하게 해주는거다
보통은
얘가 많이 씀.
req.session.name = 'downy'; // 세션 등록
req.sessionID; // 세션 ID 확인
req.session.destroy(); // 세션 모두 제거
[중요]
express-session으로 만들어진 req.session 객체에
값 넣거나 삭제하여 세션 변경 할 수있다
(세션을 한번에 삭제 하려면 req.session.destroy(); 쓰면됨)
req.session.save();쓰면 강제 저장 되는데.. 자동 저장이 되므로 굳이 쓸 필욘 없음
미들웨어 특성
미들 웨어를 직접 만들어도 보고!
다른 사람이 만든 미드웨어를
설치 해서 사용도 해봤다
< 특 정 정 리 >
- 미들 웨어는 req, res, next 를 매개변수로 갖는 함수로써
app.use / app.get / app.post 등으로 장착이 된다
(Error 처리만 err, req, res, next 총 4개의 매개 변수를 갖음)
- 특정 주소의 요청에만 미들웨어가 돌아가게 하려면
첫번째 인수로 주소를 넣으면 된다
app.use(
morgan('dev'),
express.static('/', path.join(__dirname, 'public')),
express.json(),
express.urlencoded({ extended: fale }),
cookieParser(process.env.COOKIE_SECRET),
};
- 오른쪽과 같이 각자 넣은 미들웨어를 왼쪽처럼도
한번에 묶어서도 가능하고
- 안에 next()가 들어있어 굳이 호출 안해도 되지만
저걸로 호출 안하는 미들웨어 같은 경우 res.send(),
res.sendFile() 메서드 등르로 응답을 보내줘야 한다
- express.static 같은 미들웨어는 정적파일을 제공 할 때
res.sendFile 메서드로 응답을 보낸다.
(정정파일 제공할 경우 : express.json, express.urlencoded,
cookieParser 미들웨어는 실행되지 않음)
- 다음 미들웨어로 넘어가기위한 next() 안에 인수를 넣어줄
수 도 있다.
( next('route') 를 넣게되면 라우터의 미들웨어로 넘어가거나
그 외의 인수를 넣을 경우 에러 처리 미들웨어로 이동 한다)
- 미들웨어간 데이터를 주고 받을 수도 있다
세션을 쓴다면 req.session 객체 에 데이터를 넣어도 되나
세션이 유지되는 동안 데이터도 쭉 유지된다는 단점이 있다.
만약 요청 끝날 때 까지만 데이터를 유지 하고싶다면
app.use((req, res, next) => {
req.data = '입력 데이터';
next();
}, (req, res, next) => {
consol.log(req.data); // 데이터 받기
next();
});
현재 요청 처리 되는 동안 req.data를 통해
미들웨어간 데이터를 공유 할 수있다
새 요청이 들어올 시 저 req.data는 초기화 된다.
(속성명이 꼭 data일 필요는 없으며 다른 미들웨어간
겹치는 일이 없게 해야 한다. .)
미들웨어 안에 미들웨어 넣기
app.use(morgan('dev'));
app.use((req, res, next) => {
morgan('dev')(req, res, next);
});
위의 두가지 방식은 서로 같은 기능을 수행 하고
이게 유용한 이유는 기존 미들웨어 기능을 호가장 할수 있고
// 조건문에 따른 다른 미들웨어를 적용하는 방법
app.use((req, res, next) => {
if (process.env.NODE_ENV === 'production') {
morgan('combined')(req, res, next);
} else {
morgan('dev')(req, res, next);
});
과 같이 분기 처리를 할 수도 있....다
(생각해보니 이게 말이여 방구여..
당근 쿵따리 샤바라 아님? 아니
if문을 왜 배움? switch문으로도 될꺼 같은ㄷ..?)
multer
사진, 영상 등을 포함환 여러가지 파일 형식의 멀티파트 형식으로 업로드 할때 쓰는 미들웨어
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="image" />
<input type="text name="title" />
<button type="submit">업로드</button>
</form>
enctype이 multipart/form-data인 폼을 통해 업로드 하는 데이터 형식을 말함
이런식으로 하면 멀티파트 형식으로 데이터를 업로드 할 수 있음
(서버 쪽 라우터를 만들어야 작동함)
이런 폼 통한 업로드하는 파일은 body-parser로 처리가 안되고
직접 파싱(해석)도 어려우니 multer 미들웨어를 따로 써서 사용하면 편함
설치 하면 이 안엔 여러 미들웨어가 들어 있다
storage 속성은 어디에(destination)
어떤 이름(filename)으로 저장 할지 넣는것
저 두 함수의 req매개변수엔 요청정보가,
file객체엔 업로드한 파일 정보가 있다
done 매개변수는 함수다
첫번째 인수로 에러가 있음 에러넣고,
두번째 인수로 실경로나 파일명을 넣는다
req나 file 데이터를 가공해 done로 넘기는 형식.
[ 현재꺼 해석 ]
uploads라는 폴더에 [파일명+현재 시간.확장자]파일명으로 업로드를 한다
현재 시간을 넣는 이유는 업로드 파일명이 겹쳐져 덮어쓰기 되는걸 방지하기 위함
limites 속성은 업로드에 대한 제한 사항을 설정 한다
파일의 사이즈를 5MB로 제한 두었다
저걸 실제로 쓴다면 폴더명이
가 꼭 존재 해야 한다
경로도 저렇게 uploads/라고 되있어야 한다.
const fs = require('fs');
try {
fs.readdirSync('uploads');
} catch (error) {
consol.error('uploads 폴더가 없습니다. 생성하세요.');
fs.mkdirSync('uploads');
}
이렇게 하면 upload 변수가 생기는데 여기에 다양한 미들웨어가 들어 있다
[ 파일 하나만 업로드 하는 경우 ]
single 미들웨어를 라우터 미들웨어 앞에 넣어두면
multer설정 따라 파일 업로드 후 req.file객체 생성됨
인수는 input 태그의 name이나 form 데이터의 key와 일치하게 넣으면 됨
업로드 성공시 => req.file 객체 안에 있음
req.body 안에는 파일이 아닌 데이터인 title가 들어 있다
res.file 객체
{
fieldname: 'img',
originalname: 'nodejs.png',
encoding: '7bit',
mimetype: 'image/pug',
destination: 'uploads/',
filename: 'nodejs1514197844339.png',
path: 'uploads\\nodejs1514197844339.png',
size: 53357
}
[ 파일 여러개를 업로드 하는 경우 ]
HTML의 input 태그에 multple 를 쓰면 된다
미들웨어는 single대신 array로 쓰면 됨
html | array 미들웨어 |
![]() |
![]() |
업로드 결과 역시 req.file 대신 req.files 가 배열에 들어있음
[ 파일 여러개를 업로드 하는..데 input이나 form 태그의 키가 다를 경우 ]
html | files 미들웨어 |
![]() |
![]() |
업로드 결과 req.files.image1, req.files.image2 각각 들어있다
[ 파일을 업로드 하지 않고도 멀티파트 형식으로 업로드 하는 경우 ]
이때는 none 미들웨어를 쓰면 된다
html | none 미들웨어 |
![]() |
![]() |
파일 업로드 하지 않으므로 req.body에는 아무것도 없다
multer | → | single | → | 이미지 하나 req.file 나머지 정보 req.body |
→ | array | ↘ | 이미지들 req.files 나머지 정보 req.body |
|
→ | fields | ↗ | ||
→ | none | → | 모든 정보를 req.body |
app.js | multipart.html |
![]() |
![]() |
근데 이미지나 영상등 업로드 하고 내려받고 그럴적에...
서버가 아니라 DB에 담겨있지 않음???
서버에 폴더 만들어 저장하는 방법은 이런식으로 진행된다고 알았으니. .
이제 이걸 DB에 저장 하려면 어떻게 하는가 공부 하면 되겠군
'Back-End Frameworks > Node.js' 카테고리의 다른 글
12)Nodejs_ MySQL(1)_SQL언어를 쓰는 관계형 DBMS (0) | 2023.07.19 |
---|---|
11)Nodejs_ Express Web Server_(2) Router, req res ,Template Engine(일단 보류. .ㅎㅎ) (0) | 2023.07.18 |
9)Nodejs_ npm(패키지 메니져)_(2) npm의 버전, 명령어, 배포 (0) | 2023.07.13 |
8)Nodejs_ npm(패키지 메니져)_(1) (0) | 2023.07.13 |
7)Nodejs_http로 서버 만들기(3)_https, http2, cluster (0) | 2023.07.12 |