// 认证工具函数 const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); // JWT 密钥 - 必须通过环境变量设置,不提供默认值 const JWT_SECRET = process.env.JWT_SECRET; const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || '24h'; if (!JWT_SECRET) { console.error('⚠️ 警告:未设置 JWT_SECRET 环境变量,请在 .env 文件中配置'); } /** * 密码哈希 * @param {string} password - 明文密码 * @returns {string} - 哈希后的密码 */ function hashPassword(password) { const saltRounds = 12; // 推荐值:10-14 return bcrypt.hashSync(password, saltRounds); } /** * 验证密码 * @param {string} password - 明文密码 * @param {string} hash - 数据库中的哈希密码 * @returns {boolean} - 是否匹配 */ function verifyPassword(password, hash) { return bcrypt.compareSync(password, hash); } /** * 生成 JWT Token * @param {object} payload - token 载荷 { id, username, role } * @returns {string} - JWT token */ function generateToken(payload) { return jwt.sign(payload, JWT_SECRET, { expiresIn: JWT_EXPIRES_IN, issuer: 'company-finance-system', audience: 'company-finance-client' }); } /** * 验证 JWT Token * @param {string} token - JWT token * @returns {object|null} - 解码后的 payload 或 null */ function verifyToken(token) { try { return jwt.verify(token, JWT_SECRET); } catch (error) { return null; } } /** * 从请求头中提取 token * @param {object} req - Express 请求对象 * @returns {string|null} - token 或 null */ function extractToken(req) { const authHeader = req.headers.authorization; if (authHeader && authHeader.startsWith('Bearer ')) { return authHeader.substring(7); } return null; } module.exports = { hashPassword, verifyPassword, generateToken, verifyToken, extractToken };