Files
TK-FB-Project/api.hyungi.net/models/projectModel.js
Hyungi Ahn 790d12fe13 feat: 토큰 만료 시 자동 로그아웃 기능 추가 및 테이블명 수정
🔐 토큰 만료 시 자동 로그아웃 기능:
1. JWT 토큰 만료 시간 대폭 연장:
   - 액세스 토큰: 24시간 → 7일
   - 리프레시 토큰: 7일 → 30일
   - 사용자 편의성 크게 향상

2. 토큰 만료 감지 및 처리:
   - isTokenExpired() 함수 추가
   - JWT 페이로드 파싱하여 exp 확인
   - 현재 시간과 비교하여 만료 여부 판단

3. 자동 로그아웃 처리:
   - API 호출 시 401 오류 감지
   - 주기적 토큰 만료 확인 (5분마다)
   - 만료 시 자동 인증 데이터 정리
   - 사용자 알림 후 로그인 페이지 리다이렉트

4. 개선된 인증 데이터 관리:
   - clearAuthData() 함수로 통합 관리
   - token, user, userInfo, currentUser 모두 정리
   - 메모리 누수 방지

🐛 데이터베이스 테이블명 수정:
1. projectModel.js:
   - Projects → projects (대문자 → 소문자)
   - 실제 DB 테이블명과 일치

2. taskModel.js:
   - Tasks → tasks (대문자 → 소문자)
   - 실제 DB 테이블명과 일치

3. API 오류 해결:
   - '테이블이 존재하지 않습니다' 오류 수정
   - projects, tasks API 정상 작동

 사용자 경험 개선:
- 토큰 만료로 인한 예상치 못한 오류 방지
- 명확한 만료 알림 메시지
- 자동 로그아웃으로 보안 강화
- 더 긴 세션 유지로 편의성 향상

🔧 기술적 개선:
- JWT 페이로드 안전한 파싱
- 에러 핸들링 강화
- 주기적 백그라운드 확인
- 전역 함수로 재사용성 향상

🎯 결과:
- 안정적인 인증 시스템
- 사용자 친화적인 세션 관리
- 보안성과 편의성의 균형
- API 호출 오류 해결

테스트:
- 토큰 만료 후 자동 로그아웃 확인
- projects, tasks API 정상 작동 확인
2025-11-03 12:49:25 +09:00

97 lines
2.2 KiB
JavaScript

const { getDb } = require('../dbPool');
const create = async (project, callback) => {
try {
const db = await getDb();
const {
job_no, project_name,
contract_date, due_date,
delivery_method, site, pm
} = project;
const [result] = await db.query(
`INSERT INTO projects
(job_no, project_name, contract_date, due_date, delivery_method, site, pm)
VALUES (?, ?, ?, ?, ?, ?, ?)`,
[job_no, project_name, contract_date, due_date, delivery_method, site, pm]
);
callback(null, result.insertId);
} catch (err) {
callback(err);
}
};
const getAll = async (callback) => {
try {
const db = await getDb();
const [rows] = await db.query(
`SELECT * FROM projects ORDER BY project_id DESC`
);
callback(null, rows);
} catch (err) {
callback(err);
}
};
const getById = async (project_id, callback) => {
try {
const db = await getDb();
const [rows] = await db.query(
`SELECT * FROM projects WHERE project_id = ?`,
[project_id]
);
callback(null, rows[0]);
} catch (err) {
callback(err);
}
};
const update = async (project, callback) => {
try {
const db = await getDb();
const {
project_id, job_no, project_name,
contract_date, due_date,
delivery_method, site, pm
} = project;
const [result] = await db.query(
`UPDATE projects
SET job_no = ?,
project_name = ?,
contract_date = ?,
due_date = ?,
delivery_method= ?,
site = ?,
pm = ?
WHERE project_id = ?`,
[job_no, project_name, contract_date, due_date, delivery_method, site, pm, project_id]
);
callback(null, result.affectedRows);
} catch (err) {
callback(new Error(err.message || String(err)));
}
};
const remove = async (project_id, callback) => {
try {
const db = await getDb();
const [result] = await db.query(
`DELETE FROM projects WHERE project_id = ?`,
[project_id]
);
callback(null, result.affectedRows);
} catch (err) {
callback(err);
}
};
module.exports = {
create,
getAll,
getById,
update,
remove
};