본문 바로가기

Study Information Technology

웹 기반 할 일 목록 애플리케이션 개발 사용자 인증 및 지속적인 데이터 저장

728x90
반응형

웹 기반 할 일 목록 애플리케이션 개발: 사용자 인증 및 지속적인 데이터 저장

Overview

웹 기반 할 일 목록 애플리케이션을 개발할 때 사용자 인증과 지속적인 데이터 저장은 핵심 기능입니다. 이 설명에서는 사용자 인증 기능을 어떻게 구현할 수 있는지와 데이터를 어떻게 지속적으로 저장할 수 있는지에 대해 자세히 설명하겠습니다. 예제 코드를 포함해 각 단계별로 설명하며, 발생할 수 있는 에러와 해결책도 함께 다루겠습니다.


1. 사용자 인증 구현

사용자 인증은 웹 애플리케이션에서 사용자 정보를 안전하게 관리하고, 사용자가 자신의 데이터를 보호할 수 있도록 하는 중요한 기능입니다. 인증 구현에는 여러 가지 방법이 있지만, 이번에는 JWT (JSON Web Token)를 사용한 방법을 설명하겠습니다. JWT는 사용자 정보를 안전하게 전달하는 데 사용되는 토큰 기반 인증 방식입니다.

1.1. JWT 인증 개요

JWT는 세 가지 부분으로 나뉩니다:

  • Header (헤더): 토큰의 타입과 서명 알고리즘을 지정합니다.
  • Payload (페이로드): 사용자 정보와 같은 데이터를 포함합니다.
  • Signature (서명): 토큰의 무결성을 검증하기 위해 사용하는 서명입니다.

헤더와 페이로드는 Base64로 인코딩되며, 서명은 비밀 키를 사용하여 생성됩니다.

1.2. JWT 인증 흐름

  1. 사용자 로그인: 사용자가 로그인 폼을 통해 이메일과 비밀번호를 제출합니다.
  2. 서버 검증: 서버는 이메일과 비밀번호를 검증하여 사용자가 존재하는지 확인합니다.
  3. 토큰 생성: 검증이 성공하면, 서버는 JWT를 생성하여 클라이언트에 반환합니다.
  4. 토큰 저장: 클라이언트는 JWT를 로컬 스토리지나 쿠키에 저장합니다.
  5. 요청 시 토큰 전송: 클라이언트는 서버에 요청할 때마다 JWT를 Authorization 헤더에 포함시켜 전송합니다.
  6. 서버 검증: 서버는 수신한 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. 데이터 지속성 구현

데이터를 지속적으로 저장하려면 데이터베이스를 사용하는 것이 일반적입니다. 이 설명에서는 MongoDBMongoose를 사용하여 데이터를 저장하는 방법을 설명하겠습니다. MongoDB는 문서 지향 데이터베이스로, 유연한 스키마를 제공합니다. Mongoose는 MongoDB를 더 쉽게 사용할 수 있도록 도와주는 ODM (Object Data Modeling) 라이브러리입니다.

2.1. MongoDB와 Mongoose 설정

  1. MongoDB 설치 및 실행: MongoDB를 설치하고 실행합니다. MongoDB 공식 문서를 참조하여 설치할 수 있습니다.
  2. Mongoose 설치: Node.js 프로젝트에서 Mongoose를 설치합니다.
npm install mongoose
  1. 데이터베이스 연결: 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));
  1. 모델 정의: 할 일 목록의 스키마를 정의하고 모델을 생성합니다.
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);
  1. 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를 활용한 웹 애플리케이션 개발에 필요한 기초적인 정보를 제공합니다.

728x90
반응형