오늘의 할 일
- 공통 응답 모듈 만들기
- 세션관리 모듈 만들기(클라이언트가 요청하는 모든 API(로그인 제외)헤더에 토큰 있는지 검사하는 모듈 만들기)
- 파일 업/다운로드 로그인한 사용자 검사 추가
1. 공통 응답 모듈 만들기
function success(status, message, data) {
return {
success: true,
status: status,
message: message,
data: data,
};
}
function fail(status, message) {
return {
success: false,
status: status,
message: message,
};
}
module.exports = { success, fail };
공통으로 들어가던 응답부분을 모듈로 따로 만들어 중복으로 작성되던 코드를 줄임
공통 모듈 적용 전
공통 모듈 적용 후
2. 세션관리 모듈 만들기(클라이언트가 요청하는 모든 API(로그인 제외)헤더에 토큰 있는지 검사하는 모듈 만들기)
var UserRealm = require("../db/realm");
function session(req, res, next) {
// 헤더에서 이메일과 토큰 추출
const email = req.headers.email;
const token = req.headers.token;
if (!email || !token) {
return res.status(401).send({ message: "이메일과 토큰을 넣어주세요." });
}
try {
const user = UserRealm.objects("User").filtered(
`email = "${email}" AND token = "${token}"`
)[0];
console.log(JSON.stringify(user));
console.log(user.length);
if (user) {
// 사용자가 존재하고 토큰이 일치하면 인증 성공
// 토큰 만료시간 갱신
UserRealm.write(() => {
user.tokenExp = new Date();
});
console.log("여기는 사용자가 존재하고 토큰이 일치한것");
console.log(JSON.stringify(user));
return user;
} else {
// 사용자가 없거나 토큰이 일치하지 않으면 인증 실패
return 0;
}
} catch (error) {
console.log(error);
return 0;
}
}
// 토큰 만료시간 확인 코드 필요
module.exports = session;
3. 파일 업/다운로드 로그인한 사용자 검사 추가
위에서 만든 세션 관리 모듈을 이용해서 파일 업/다운로드 실행 전 클라이언트의 헤더를 검사함
이메일, 토큰값을 확인하여 유효한 계정만 파일 업다운로드를 실행 할 수 있음
const express = require("express");
const router = express.Router();
const multer = require("multer"); // multer 모듈: 파일 업로드를 위한 multipart/form-data 를 다루기 위한 node.js 의 미들웨어
const fs = require("fs"); // fs 모듈: 파일 시스템을 조작하는 다양한 메서드 제공
const path = require("path"); // path 모듈: 파일 및 디렉토리 경로 작업을 위한 다양한 메서드 제공
const session = require("../module/sessionModule"); // session 모듈
const response = require("../util/response"); // 공통 응답 모듈
//------------------------------ 파일 업로드 관련 설정------------------------------//
// 파일을 업로드할 uploads 폴더 생성
fs.readdir("uploads", (error) => {
if (error) {
console.log("uploads 폴더를 생성합니다.");
fs.mkdirSync("uploads");
}
});
/*
파일 업로드 처리를 위해 multer 모듈 사용
multer.diskStorage: 파일 저장 방식을 정하는 옵션
destination: 파일이 저장될 경로를 정하는 옵션
cb: 콜백함수로 전송된 파일을 저장할 폴더를 지정하는데 사용
첫 번째 매개변수: 에러가 발생하면 해당 에러를 전달
두 번째 매개변수: 실제 저장할 폴더를 지정
filename: 파일의 이름을 정하는 옵션
cb: 콜백함수로 전송된 파일을 저장할 이름을 지정하는데 사용
첫 번째 매개변수: 에러가 발생하면 해당 에러를 전달
두 번째 매개변수: 파일의 이름을 지정
*/
const upload = multer({
storage: multer.diskStorage({
// 파일 저장 경로 설정
destination(req, file, cb) {
cb(null, "uploads/"); // cb 콜백 함수를 통해 전송된 파일 저장 디렉토리 설정, 'uploads/' 디렉토리로 지정
},
// 파일 저장명 설정
filename(req, file, cb) {
cb(null, file.originalname);
},
}),
// 파일 최대 용량
limits: { fileSize: 5 * 1024 * 1024 },
});
//------------------------------ api 요청 ------------------------------//
/* GET 파일 업로드 */
// 단일 파일 업로드 multer.single(fileName)
router.post("/upload", upload.single("file"), function (req, res, next) {
result = session(req, res, next);
console.log(`result!!!! ${result}`);
if (result) {
console.log("단일 파일 업로드 요청");
console.log(req.file);
const imagePath = req.file.path;
if (imagePath === undefined) {
return res.status(400).send(response.fail(400, "파일이 없습니다."));
}
res
.status(200)
.send(
response.success(200, "파일 업로드 성공", `저장경로: /${imagePath}`)
);
}
});
// n개 파일 업로드 multer.array(, 개수제한)
router.post("/uploads", upload.array("files", 10), function (req, res, next) {
console.log(req.files);
res
.status(200)
.send(
response.success(200, "파일 업로드 성공", `파일개수: ${req.files.length}`)
);
});
module.exports = router;
업로드 정상응답
업로드 비정상응답 - 헤더에 토큰 없는 경우
파일 다운로드
var express = require("express");
var router = express.Router(); // router 객체는 express.Router()로 만듦
const multer = require("multer");
const path = require("path");
const fs = require("fs");
const session = require("../module/sessionModule"); // session 모듈
const response = require("../util/response"); // 공통 응답 모듈
//------------------------------ api 요청 ------------------------------//
/* GET users listing. */
router.get("/download/:fileName", function (req, res, next) {
result = session(req, res, next);
if (result) {
const fileName = req.params.fileName;
const filePath = `uploads/${fileName}`;
console.log(`fileName: ${fileName}`);
console.log(`filePath: ${filePath}`);
const ch = fs.existsSync(filePath);
console.log(`파일 존재여부: ${ch}`);
// 다운로드 요청한 파일이 존재하는지 확인
if (fs.existsSync(filePath)) {
// 파일의 MIME 유형 설정(이미지, pdf, txt 등)
res.setHeader("Content-Type", getMimeType(fileName));
// 파일의 Content-Disposition 헤더를 "inline"으로 설정하여 파일을 브라우저에서 바로 보기
res.setHeader("Content-Disposition", "inline; filename=" + fileName);
// 파일 스트림을 응답에 연결
const fileStream = fs.createReadStream(filePath);
fileStream.pipe(res);
} else {
res.status(404).send(response.fail(404, "파일이 존재하지 않습니다."));
}
}
});
//------------------------------ 메서드 ------------------------------//
// 파일 유형을 확인하고 MIME 유형을 반환해주는 메서드
function getMimeType(fileName) {
const extname = path.extname(fileName);
switch (extname.toLowerCase()) {
case ".png":
return "image/png";
case ".jpg":
case ".jpeg":
return "image/jpeg";
case ".pdf":
return "application/pdf";
case ".txt":
return "text/plain";
default:
return "application/octet-stream";
}
}
module.exports = router; // 라운터를 모듈로 만듦
다운로드 정상응답
토큰이 없는 경우 응답
'Node.js' 카테고리의 다른 글
[Node.js] 계정관리 서버 프로젝트 3 (0) | 2023.11.15 |
---|---|
[Node.js] exress 프로젝트 로그 관리 방법 (0) | 2023.11.15 |
[Node.js] 계정관리 서버 프로젝트 1 (0) | 2023.11.14 |
[Node.js] CommonJS 모듈 (0) | 2023.11.13 |
[Node.js] 모듈 (0) | 2023.11.13 |