.env
JWT_SECRET_KEY=secret
JWT_EXPIRES=5m
BCRYPT_SALT_ROUNDS=12
SERVER_PORT=8000
config.js
import dotenv from "dotenv";
dotenv.config();
export const config = {
jwtSecretKey: process.env.JWT_SECRET_KEY,
jwtExpires: process.env.JWT_EXPIRES,
bcryptSaltRounds: parseInt(process.env.BCRYPT_SALT_ROUNDS),
port: parseInt(process.env.SERVER_PORT),
};
app.js
import express from "express";
import helmet from "helmet";
import morgan from "morgan";
import cors from "cors";
import tweetController from "./tweet/tweet.controller.js";
import authController from "./auth/auth.controller.js";
import { config } from "../config.js";
const app = express();
app.use(express.json());
app.use(morgan("dev"));
app.use(helmet());
app.use(cors());
app.use("/tweet", tweetController);
app.use("/auth", authController);
app.use((req, res, next) => {
res.sendStatus(404);
});
app.use((err, req, res, next) => {
res.sendStatus(500);
});
app.listen(config.port);
auth.js
import jwt from "jsonwebtoken";
import { config } from "../../config.js";
import * as userRepository from "../user/user.repository.js";
export const auth = async (req, res, next) => {
const authHeader = req.get("Authorization");
if (authHeader && authHeader.startsWith("Bearer ")) {
const token = authHeader.split(" ")[1];
jwt.verify(token, config.jwtSecretKey, async (err, data) => {
if (err) {
return res.status(401).json({ message: "인증 에러" });
}
else {
const user = await userRepository.findById(data.id);
if (user) {
req.token = token;
req.userId = user.id;
return next();
}
else {
return res.status(401).json({ message: "인증 에러" });
}
}
});
}
else {
return res.status(401).json({ message: "인증 에러" });
}
};
auth.service.js
import * as userRepository from "../user/user.repository.js";
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
import { config } from "../../config.js";
const createToken = (id) => {
return jwt.sign({ id }, config.jwtSecretKey, {
expiresIn: config.jwtExpires,
});
};
export const signup = async (req, res) => {
const { username, password, name, email } = req.body;
const user = await userRepository.findByUsername(username);
if (user) {
return res.status(409).json({ message: `이미 가입된 유저입니다.` });
}
const hashed = await bcrypt.hash(password, config.bcryptSaltRounds);
const createdUser = await userRepository.createUser({
username,
password: hashed,
name,
email,
});
const token = createToken(createdUser.id);
res.status(201).json({ token, username });
};
export const login = async (req, res) => {
const { username, password } = req.body;
const user = await userRepository.findByUsername(username);
if (!user) {
return res
.status(401)
.json({ message: "아이디 혹은 비밀번호가 틀렸습니다." });
}
const isValidPassword = await bcrypt.compare(password, user.password);
if (!isValidPassword) {
return res
.status(401)
.json({ message: "아이디 혹은 비밀번호가 틀렸습니다." });
}
const token = createToken(user.id);
res.status(200).json({ token, username });
};
export const me = async (req, res) => {
const user = await userRepository.findById(req.userId);
if (user) {
return res
.status(200)
.json({ token: req.token, username: user.username });
}
res.status(404).json({ message: "유저가 존재하지 않습니다." });
};