웹 기반 할 일 목록 애플리케이션 개발: 사용자 인증 및 지속적인 데이터 저장
Overview
웹 기반 할 일 목록 애플리케이션을 개발할 때 사용자 인증과 지속적인 데이터 저장은 핵심 기능입니다. 이 설명에서는 사용자 인증 기능을 어떻게 구현할 수 있는지와 데이터를 어떻게 지속적으로 저장할 수 있는지에 대해 자세히 설명하겠습니다. 예제 코드를 포함해 각 단계별로 설명하며, 발생할 수 있는 에러와 해결책도 함께 다루겠습니다.
1. 사용자 인증 구현
사용자 인증은 웹 애플리케이션에서 사용자 정보를 안전하게 관리하고, 사용자가 자신의 데이터를 보호할 수 있도록 하는 중요한 기능입니다. 인증 구현에는 여러 가지 방법이 있지만, 이번에는 JWT (JSON Web Token)를 사용한 방법을 설명하겠습니다. JWT는 사용자 정보를 안전하게 전달하는 데 사용되는 토큰 기반 인증 방식입니다.
1.1. JWT 인증 개요
JWT는 세 가지 부분으로 나뉩니다:
- Header (헤더): 토큰의 타입과 서명 알고리즘을 지정합니다.
- Payload (페이로드): 사용자 정보와 같은 데이터를 포함합니다.
- Signature (서명): 토큰의 무결성을 검증하기 위해 사용하는 서명입니다.
헤더와 페이로드는 Base64로 인코딩되며, 서명은 비밀 키를 사용하여 생성됩니다.
1.2. JWT 인증 흐름
- 사용자 로그인: 사용자가 로그인 폼을 통해 이메일과 비밀번호를 제출합니다.
- 서버 검증: 서버는 이메일과 비밀번호를 검증하여 사용자가 존재하는지 확인합니다.
- 토큰 생성: 검증이 성공하면, 서버는 JWT를 생성하여 클라이언트에 반환합니다.
- 토큰 저장: 클라이언트는 JWT를 로컬 스토리지나 쿠키에 저장합니다.
- 요청 시 토큰 전송: 클라이언트는 서버에 요청할 때마다 JWT를 Authorization 헤더에 포함시켜 전송합니다.
- 서버 검증: 서버는 수신한 JWT의 유효성을 검증하여 요청을 처리합니다.
1.3. JWT 인증 예제
먼저, Node.js와 Express를 사용하여 간단한 서버를 구현하고 JWT를 이용한 인증을 추가하겠습니다.
서버 설정
const express = require('express');
const jwt = require('jsonwebtoken');
const bodyParser = require('body-parser');
const app = express();
const PORT = 3000;
const SECRET_KEY = 'your_secret_key';
app.use(bodyParser.json());
// 로그인 엔드포인트
app.post('/login', (req, res) => {
const { email, password } = req.body;
// 실제 애플리케이션에서는 데이터베이스에서 사용자 정보를 확인합니다.
if (email === 'user@example.com' && password === 'password123') {
// JWT 생성
const token = jwt.sign({ email }, SECRET_KEY, { expiresIn: '1h' });
res.json({ token });
} else {
res.status(401).json({ message: 'Invalid credentials' });
}
});
// 인증이 필요한 엔드포인트
app.get('/protected', (req, res) => {
const token = req.headers['authorization'];
if (!token) return res.status(403).json({ message: 'No token provided' });
jwt.verify(token, SECRET_KEY, (err, decoded) => {
if (err) return res.status(500).json({ message: 'Failed to authenticate token' });
res.json({ message: 'Access granted', user: decoded.email });
});
});
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
클라이언트 설정
클라이언트에서 로그인 후 JWT를 저장하고 인증이 필요한 요청에 토큰을 포함시켜야 합니다. 여기서는 브라우저의 fetch
API를 사용하는 방법을 보여드립니다.
// 로그인 요청
fetch('/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: 'user@example.com', password: 'password123' })
})
.then(response => response.json())
.then(data => {
localStorage.setItem('token', data.token);
})
.catch(error => console.error('Error:', error));
// 인증된 요청
const token = localStorage.getItem('token');
fetch('/protected', {
method: 'GET',
headers: { 'Authorization': token }
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
1.4. 발생할 수 있는 에러와 해결책
- 401 Unauthorized: 잘못된 자격 증명으로 인해 발생할 수 있습니다. 사용자가 입력한 이메일이나 비밀번호를 확인하거나, 서버에서 데이터베이스 쿼리를 검토하여 문제가 있는지 확인합니다.
- 500 Internal Server Error: 서버에서 JWT 서명 검증에 실패했을 때 발생합니다. 비밀 키가 일치하는지 확인하고, JWT 라이브러리의 버전을 검토합니다.
2. 데이터 지속성 구현
데이터를 지속적으로 저장하려면 데이터베이스를 사용하는 것이 일반적입니다. 이 설명에서는 MongoDB와 Mongoose를 사용하여 데이터를 저장하는 방법을 설명하겠습니다. MongoDB는 문서 지향 데이터베이스로, 유연한 스키마를 제공합니다. Mongoose는 MongoDB를 더 쉽게 사용할 수 있도록 도와주는 ODM (Object Data Modeling) 라이브러리입니다.
2.1. MongoDB와 Mongoose 설정
- MongoDB 설치 및 실행: MongoDB를 설치하고 실행합니다. MongoDB 공식 문서를 참조하여 설치할 수 있습니다.
- Mongoose 설치: Node.js 프로젝트에서 Mongoose를 설치합니다.
npm install mongoose
- 데이터베이스 연결: Mongoose를 사용하여 MongoDB에 연결합니다.
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/todolist', {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => console.log('MongoDB connected'))
.catch(err => console.error('MongoDB connection error:', err));
- 모델 정의: 할 일 목록의 스키마를 정의하고 모델을 생성합니다.
const todoSchema = new mongoose.Schema({
text: { type: String, required: true },
completed: { type: Boolean, default: false },
user: { type: String, required: true }
});
const Todo = mongoose.model('Todo', todoSchema);
- CRUD 연산 구현: Create, Read, Update, Delete 연산을 구현합니다.
// 할 일 추가
app.post('/todos', (req, res) => {
const { text, user } = req.body;
const newTodo = new Todo({
text,
user
});
newTodo.save()
.then(todo => res.json(todo))
.catch(err => res.status(400).json({ error: err.message }));
});
// 할 일 목록 조회
app.get('/todos', (req, res) => {
Todo.find()
.then(todos => res.json(todos))
.catch(err => res.status(500).json({ error: err.message }));
});
// 할 일 수정
app.put('/todos/:id', (req, res) => {
const { text, completed } = req.body;
Todo.findByIdAndUpdate(req.params.id, { text, completed }, { new: true })
.then(todo => res.json(todo))
.catch(err => res.status(400).json({ error: err.message }));
});
// 할 일 삭제
app.delete('/todos/:id', (req, res) => {
Todo.findByIdAndDelete(req.params.id)
.then(() => res.json({ message: 'Todo deleted' }))
.catch(err => res.status(500).json({ error: err.message }));
});
2.2. 발생할 수 있는 에러와 해결책
- 400 Bad Request: 잘못된 데이터 형식으로 인해 발생할 수 있습니다. 전송하는 데이터의 형식을 확인하고, 스키마와 일치하는지 확인합니다.
- 500 Internal Server Error: 데이터베이스 연결 문제나 쿼리 오류가 있을 수 있습니다. MongoDB 서버가 실행 중인지 확인하고, 쿼리 문법을 검토합니다.
참고문서
이 문서들은 JWT 인증과 데이터베이스 연동, 그리고 Express와 Mongoose를 활용한 웹 애플리케이션 개발에 필요한 기초적인 정보를 제공합니다.
'Study Information Technology' 카테고리의 다른 글
TicTacToe 게임 설계로 배우는 게임 메커니즘과 사용자 상호작용 (0) | 2024.08.23 |
---|---|
날씨 예측 앱 개발 API를 활용한 데이터 가져오기와 표시 (0) | 2024.08.23 |
실시간 업데이트와 버전 관리를 갖춘 협업 문서 편집기 설계 (0) | 2024.08.23 |
개인 습관 추적기 디자인 일상 루틴 및 행동 모니터링과 개선 (0) | 2024.08.23 |
전자상거래 웹사이트 개발 제품 목록 쇼핑 카트 결제 기능 구현 (0) | 2024.08.23 |