Nodebird 서비스와 데이터베이스를 공유하는 프로젝트 구조 갖추기(1)
다른 서비스에 Nodebird 서비스의 게시글, 해시태그, 사용자 정보를 JSON 형식으로 제공할 것입니다. 단, 인증을 받은 사용자에게만 일정한 할당량 안에서 API를 호출할 수 있도록 허용할 것입니다.
우선 nodebird-api 폴더를 만들고 package.json 파일을 생성합니다. npm init으로 생성한 후 dependenciese들을 설치해도 되고, 이제 package.json을 복사해도 됩니다. 새로 추가된 패키지는 uuid이며, 고유한 랜덤 문자열을 만들어내는 데 사용됩니다.
{
"name": "nodebird-api",
"version": "0.0.1",
"description": "NodeBird API 서버",
"main": "app.js",
"scripts": {
"start": "nodemon app",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Cherry",
"license": "ISC",
"dependencies": {
"bcrypt": "^4.0.1",
"cookie-parser": "^1.4.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-session": "^1.17.1",
"morgan": "^1.10.0",
"mysql2": "^2.1.0",
"nunjucks": "^3.2.1",
"passport": "^0.4.1",
"passport-kakao": "1.0.0",
"passport-local": "^1.0.0",
"sequelize": "^5.21.7",
"uuid": "^7.0.3"
},
"devDependencies": {
"nodemon": "^2.0.3"
}
}
package.json에 적힌 패키지를 설치합니다.
$ npm i
Nodebird에서 config, models, passport 폴더와 내용물들을 모두 복사해서 nodebird-api 폴더에 붙어 넣습니다. routes 폴더에서는 auth.js와 middlewares.js만 그대로 사용합니다. 마지막으로 .env 파일을 복사합니다. 다른 폴더와 파일은 새로 나올 때 마다 직접 생성하면 됩니다.
다음은 에러를 표시할 파일입니다. views 폴더를 만들고 그 폴더 안에 error.html 파일을 생성합니다.
nodebird-api/views/error.html
<h1>{{message}}</h1>
<h2>{{error.status}}</h2>
<pre>{{error.stack}}</pre>
nodebird-api/app.js
const express = require("express");
const path = require("path");
const cookieParser = require("cookie-parser");
const passport = require("passport");
const morgan = require("morgan");
const session = require("express-session");
const nunjucks = require("nunjucks");
const dotenv = require("dotenv");
dotenv.config();
const authRouter = require("./routes/auth");
const indexRouter = require("./routes");
const { sequelize } = require("./models");
const passportConfig = require("./passport");
const app = express();
passportConfig();
app.set("port", process.env.PORT || 8002);
app.set("view engine", "html", {
express: app,
watch: true,
});
sequelize
.sync({ force: false })
.then(() => {
console.log("데이터베이스 연결 성공");
})
.catch((err) => {
console.error(err);
});
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,
},
})
);
app.use("/auth", authRouter);
app.use("/", indexRouter);
app.use((req, res, next) => {
const error = new Error(`${req.method} ${req.url} 라우터가 없습니다.`);
error.status = 404;
next(error);
});
app.use((err, req, res, next) => {
res.locals.message = err.message;
res.locals.error = process.env.NODE_ENV !== "production" ? err : {};
res.status(err.status || 500);
res.render("error");
});
app.listen(app.get("port"), () => {
console.log(app.get("port"), "번 포트에서 대기 중");
});
포트 번호를 8002로 했으므로 9장의 Nodebird 앱 서버(8001번 포트) 및 추후에 만들 클라이언트인 NodeDog 서버(포트 번호 4000)와 같이 실행할 수 있습니다. 콘솔을 하나 더 열어서 서버를 실행하면 됩니다.
도메인을 등록하는 기능이 새로 생겼으므로 도메인 모델을 추가해봅시다. 도메인 모델을 추가해봅시다. 도메인은 인터넷 주소를 뜻합니다.
const Sequelize = require("sequelize");
module.exports = class Domain extends Sequelize.Model {
static(sequelize) {
return super.init(
{
host: {
type: Sequelize.STRING(80),
allowNull: false,
},
type: {
type: Sequelize.ENUM("free", "premium"),
},
clientSecret: {
type: Sequelize.UUID,
allowNull: false,
},
},
{
sequelize,
timestamps: true,
paranoid: true,
modelName: "Domain",
tableName: "domains",
}
);
}
static associate(db) {
db.Domain.belongsTo(db.User);
}
};
도메인 모델에는 인터넷 주소(host)와 도메인 종류(type), 클라이언트 비밀 키(clientSecret)가 들어갑니다.
type 컬럼을 보면 처음 보는 ENUM이라는 속성을 가지고 있습니다. 넣을 수 없는 값을 제한하는 데이터 형식입니다. 무료(free)나 프리미엄(preminum) 중에서 하나의 종류만 선택할 수 있게 했고, 이를 어겼을 때 에러가 발생합니다.
클라이언트 비밀 키는 다른 개발자들이 Nodebird의 API를 사용할 때 필요한 비밀키입니다. 이 키가 유출되면 다른 사람을 사칭해서 요청을 보낼 수 있으므로, 유출되지 않도록 주의해야 합니다. 한 가지 안전 장치로서, 요청을 보낸 도메인까지 일치해야 요청을 보낼 수 있게 제한을 둘 것입니다. clientSecret 컬럼을 UUID라는 타입을 가집니다. UUID는 충돌 가능성이 매우 적은 랜덤한 문자열입니다.
'프로그래밍 언어 > NODE JS' 카테고리의 다른 글
| JWT 토큰으로 인증하기 (1) (0) | 2025.11.22 |
|---|---|
| Nodebird 서비스와 데이터베이스를 공유하는 프로젝트 구조 갖추기(2) (0) | 2025.11.16 |
| API 서버 이해하기 (0) | 2025.11.10 |
| 프로젝트 마무리하기 (0) | 2025.11.07 |
| multer 패키지로 이미지 업로드 구현하기 (0) | 2025.11.04 |