1. JWT(JSON Web Token)
JWT는 JSON 객체를 사용해 정보를 안전하게 전송하기 위한 개방형 표준(RFC 7519)이며, JWT는 다음과 같은 세 부분으로 구성됩니다.
- Header: 토큰의 유형(type)과 서명 알고리즘(algorithm)에 대한 정보를 포함
- Payload: 사용자 정보 및 토큰의 유효 기간과 같은 클레임(claims)을 포함
- Signature: Header와 Payload를 인코딩한 후 비밀 키를 사용해 서명, 이 서명은 토큰의 무결성을 확인하는 데 사용
JWT는 서버에 상태를 저장할 필요 없이 클라이언트와 서버 간의 인증을 가능하게 합니다.
2. 사용자 인증 구현
먼저 필요한 패키지를 설치하기 위해 아래 명령어를 입력합니다.
npm install express jsonwebtoken bcryptjs dotenv
// server.js
const express = require("express");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcryptjs");
const dotenv = require("dotenv");
dotenv.config();
const app = express();
app.use(express.json());
const users = []; // 사용자 정보를 저장할 배열
다음 사용자 정보를 등록하기 위해 다음 코드를 작성합니다.
// 사용자 등록
app.post("/register", async (req, res) => {
const { username, password } = req.body;
const hashedPassword = await bcrypt.hash(password, 10);
users.push({ username, password: hashedPassword });
res.status(201).send("User registered");
});
다음 사용자 로그인을 구현하는 코드를 작성합니다.
app.post("/login", async (req, res) => {
const { username, password } = req.body;
const user = users.find((u) => u.username === username);
if (!user) return res.status(400).send("User not found");
const isValid = await bcrypt.compare(password, user.password);
if (!isValid) return res.status(403).send("invalid password");
const token = jwt.sign({ username: user.username }, process.env.JWT_SECRET, {
expiresIn: "1h",
});
res.json({ token });
});
다음 인증 미들웨어와 인증된 라우트를 작성합니다.
const authenticateJWT = (req, res, next) => {
const token = req.headers["authorization"]?.split(" ")[1];
if (!token) return res.sendStatus(408);
jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
if (err) return res.sendStatus(403);
req.user = user;
next();
});
};
// 인증된 라우트
app.get("/dashboard", authenticateJWT, (req, res) => {
res.send(`Welcome ${req.user.username}`);
});
3.Helmet 사용
Helmet은 Express 애플리케이션의 보안을 강화하기 위한 미들웨어입니다. HTTP 헤더를 설정하여 여러 가지 보안 관련 취약점을 줄일 수 있습니다.
npm install helmet
const helmet = require("helmet");
app.use(helmet());
4. CORS 설정
CORS(Cross-Origin Resource Sharing)는 다른 출처의 리소스에 대한 접근을 제어하는 매커니즘으로, Node.js에서 CORS를 설정하려면 cors 패키지를 사용할 수 있습니다.
npm install cors
const cors = require("cors");
app.use(
cors({
origin: "https://thinky.tistory.com/", // 허용할 도메인
methods: ["GET", "POST"],
})
);
5.전체 코드
const express = require("express");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcryptjs");
const dotenv = require("dotenv");
const helmet = require("helmet");
const cors = require("cors");
dotenv.config();
const app = express();
app.use(express.json());
app.use(helmet());
app.use(cors());
const users = []; // 사용자 정보를 저장할 배열
// 사용자 등록
app.post("/register", async (req, res) => {
try {
const { username, password } = req.body;
if (!username || !password) {
return res.status(400).send("Username and password are required");
}
const existingUser = users.find((user) => user.username === username);
if (existingUser) {
return res.statusCode(400).send("Username already exists");
}
const hashedPassword = await bcrypt.hash(password, 10);
users.push({ username, password: hashedPassword });
res.status(201).send("User registered");
} catch (error) {
console.error(error);
res.status(500).send("Internal Server Error");
}
});
// 사용자 조회
app.get("/users", (req, res) => {
const userList = users.map((user) => ({ username: user.username }));
res.json(userList);
});
// 사용자 로그인
app.post("/login", async (req, res) => {
try {
const { username, password } = req.body;
const user = users.find((u) => u.username === username);
if (!user) return res.status(400).send("User not found");
const isValid = await bcrypt.compare(password, user.password);
if (!isValid) return res.status(403).send("invalid password");
const token = jwt.sign(
{ username: user.username },
process.env.JWT_SECRET,
{
expiresIn: "1h",
}
);
res.json({ token });
} catch (error) {
console.error(error);
res.status(500).send("Internal Server Error");
}
});
// 인증 미들웨어
const authenticateJWT = (req, res, next) => {
const token = req.headers["authorization"]?.split(" ")[1];
if (!token) return res.sendStatus(403);
jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
if (err) return res.sendStatus(403);
req.user = user;
next();
});
};
// 인증된 라우트
app.get("/dashboard", authenticateJWT, (req, res) => {
res.send(`Welcome ${req.user.username}`);
});
// 서버 시작
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
.env 파일을 생성하고 JWT 비밀 키를 설정합니다.
JWT_SECRET=your_jwt_secret_key
서버를 실행하고 Postman에서 요청을 보냅니다. Postman에서 아래 url로 POST로 Send를 누르고 다음 설정으로 들어가 아래 데이터를 입력후 다시 Send를 눌러줍니다.
- 사용자 등록 요청:
- HTTP 메서드: POST
- URL: http://localhost:5000/register
- Body 설정:
- raw 선택
- JSON 형식으로 설정
- 아래와 같은 데이터 입력:
{
"username": "testuser",
"password": "testpassword"
}
- 사용자 조회 요청
- HTTP 메서드: GET
- URL: http://localhost:5000/users
- 요청 및 응답 확인
- 등록 후 응답 메시지 "User registered" 인지 확인합니다.
- 조회 후 응답이 JSON 형식으로 사용자 목록인지 확인
GitHub - nodeJsroom/node-js-bloging
Contribute to nodeJsroom/node-js-bloging development by creating an account on GitHub.
github.com
LIST
'Back-End > Node.js' 카테고리의 다른 글
[NodeJs] 8장 Docker(도커)를 사용한 배포 (0) | 2025.03.02 |
---|---|
[NodeJS] 7장 에러처리 (0) | 2025.02.27 |
[NodeJS] 5장 데이터베이스 연동하기 (0) | 2025.02.25 |
[NodeJS] 4장 Express.js 프레임워크 (0) | 2025.02.23 |
[NodeJS] 3장 라우팅 구현, HTTP 서버만들기 (0) | 2025.02.22 |