|
|
@@ -2,7 +2,7 @@ const express = require('express');
|
|
|
const path = require('path');
|
|
|
const fs = require('fs').promises;
|
|
|
const cors = require('cors');
|
|
|
-const session = require('express-session');
|
|
|
+const SECERT_TOKEN = 'cjy123';
|
|
|
|
|
|
const app = express();
|
|
|
const PORT = 3000;
|
|
|
@@ -10,6 +10,16 @@ const PORT = 3000;
|
|
|
// 硬编码的密码
|
|
|
const PASSWORD = 'cjy@0526';
|
|
|
|
|
|
+// 令牌 Cookie 配置
|
|
|
+const TOKEN_COOKIE_NAME = 'cjydocs.token';
|
|
|
+const TOKEN_COOKIE_OPTIONS = {
|
|
|
+ maxAge: 7 * 24 * 60 * 60 * 1000,
|
|
|
+ httpOnly: true,
|
|
|
+ secure: false,
|
|
|
+ sameSite: 'lax',
|
|
|
+ path: '/'
|
|
|
+};
|
|
|
+
|
|
|
// 目录常量
|
|
|
const DIRS = {
|
|
|
public: path.join(__dirname, 'public'),
|
|
|
@@ -43,8 +53,26 @@ function validatePath(fullPath, baseDir) {
|
|
|
}
|
|
|
|
|
|
// 检查是否已认证
|
|
|
+function parseCookies(cookieHeader) {
|
|
|
+ if (!cookieHeader || typeof cookieHeader !== 'string') {
|
|
|
+ return {};
|
|
|
+ }
|
|
|
+
|
|
|
+ return cookieHeader.split(';').reduce((acc, part) => {
|
|
|
+ const [rawKey, ...rawValue] = part.trim().split('=');
|
|
|
+ if (!rawKey) return acc;
|
|
|
+ acc[decodeURIComponent(rawKey)] = decodeURIComponent(rawValue.join('='));
|
|
|
+ return acc;
|
|
|
+ }, {});
|
|
|
+}
|
|
|
+
|
|
|
+function getCookie(req, name) {
|
|
|
+ const cookies = parseCookies(req.headers.cookie);
|
|
|
+ return cookies[name];
|
|
|
+}
|
|
|
+
|
|
|
function isAuthenticated(req) {
|
|
|
- return req.session && req.session.isAuthenticated === true;
|
|
|
+ return getCookie(req, TOKEN_COOKIE_NAME) === SECERT_TOKEN;
|
|
|
}
|
|
|
|
|
|
// 统一的错误响应助手
|
|
|
@@ -85,21 +113,6 @@ app.use(cors({
|
|
|
app.use(express.json({ limit: '10mb' })); // 增加请求体大小限制到10MB
|
|
|
app.use(express.urlencoded({ limit: '10mb', extended: true }));
|
|
|
|
|
|
-// Session 中间件
|
|
|
-app.use(session({
|
|
|
- secret: 'cjydocs-secret-key-2024', // 会话密钥
|
|
|
- resave: false,
|
|
|
- saveUninitialized: false,
|
|
|
- cookie: {
|
|
|
- maxAge: 7 * 24 * 60 * 60 * 1000, // 7天
|
|
|
- httpOnly: true,
|
|
|
- secure: false, // 如果使用 HTTPS,设置为 true
|
|
|
- sameSite: 'lax', // 允许跨站点请求携带 cookie
|
|
|
- path: '/' // Cookie 路径
|
|
|
- },
|
|
|
- name: 'cjydocs.sid', // Session cookie 名称
|
|
|
- rolling: true // 每次请求时重置过期时间
|
|
|
-}));
|
|
|
|
|
|
// 登录验证中间件
|
|
|
function requireAuth(req, res, next) {
|
|
|
@@ -162,16 +175,9 @@ app.post('/api/login', (req, res) => {
|
|
|
}
|
|
|
|
|
|
if (password === PASSWORD) {
|
|
|
- req.session.isAuthenticated = true;
|
|
|
+ res.cookie(TOKEN_COOKIE_NAME, SECERT_TOKEN, TOKEN_COOKIE_OPTIONS);
|
|
|
|
|
|
- // 保存 session 后再响应
|
|
|
- req.session.save((err) => {
|
|
|
- if (err) {
|
|
|
- console.error('Session保存失败:', err);
|
|
|
- return ErrorResponse.serverError(res, '登录失败,请重试');
|
|
|
- }
|
|
|
- res.json({ success: true, message: '登录成功' });
|
|
|
- });
|
|
|
+ res.json({ success: true, message: '登录成功' });
|
|
|
} else {
|
|
|
return ErrorResponse.unauthorized(res, '密码错误');
|
|
|
}
|
|
|
@@ -179,12 +185,8 @@ app.post('/api/login', (req, res) => {
|
|
|
|
|
|
// API: 登出
|
|
|
app.post('/api/logout', (req, res) => {
|
|
|
- req.session.destroy((err) => {
|
|
|
- if (err) {
|
|
|
- return ErrorResponse.serverError(res, '登出失败');
|
|
|
- }
|
|
|
- res.json({ success: true, message: '登出成功' });
|
|
|
- });
|
|
|
+ res.clearCookie(TOKEN_COOKIE_NAME, { path: '/' });
|
|
|
+ res.json({ success: true, message: '登出成功' });
|
|
|
});
|
|
|
|
|
|
// API: 检查登录状态
|