rentease-backend-new/middleware/tenant.js

131 lines
3.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const Tenant = require('../models/Tenant');
/**
* 租户上下文中间件
* 从请求头或JWT令牌中提取租户信息并设置到请求上下文中
*/
const tenantContextMiddleware = async (req, res, next) => {
try {
let tenantId = null;
// 1. 尝试从请求头获取租户ID
const headerTenantId = req.headers['x-tenant-id'];
if (headerTenantId) {
tenantId = parseInt(headerTenantId, 10);
}
// 2. 如果请求头中没有尝试从JWT令牌中获取
if (!tenantId && req.user && req.user.tenantId) {
tenantId = req.user.tenantId;
}
// 3. 系统管理员可以指定任意租户
if (req.user && req.user.userType === 'super_admin' && headerTenantId) {
tenantId = parseInt(headerTenantId, 10);
}
// 4. 如果没有租户ID返回错误
if (!tenantId) {
return res.status(400).json({
code: 400,
message: '缺少租户标识'
});
}
// 5. 验证租户是否存在且状态正常
const tenant = await Tenant.findOne({
where: {
id: tenantId,
status: 'active',
isDeleted: 0
}
});
if (!tenant) {
return res.status(403).json({
code: 403,
message: '租户不存在或已被禁用'
});
}
// 6. 检查租户是否过期(使用 currentPeriodEnd 判断)
if (tenant.currentPeriodEnd && new Date(tenant.currentPeriodEnd) < new Date()) {
return res.status(403).json({
code: 403,
message: '租户服务已过期'
});
}
// 7. 将租户信息附加到请求对象
req.tenantId = tenantId;
req.tenant = tenant;
next();
} catch (error) {
console.error('租户上下文中间件错误:', error);
return res.status(500).json({
code: 500,
message: '租户验证失败',
error: error.message
});
}
};
/**
* 可选租户中间件
* 用于一些不需要强制租户隔离的接口
*/
const optionalTenantMiddleware = async (req, res, next) => {
try {
let tenantId = null;
const headerTenantId = req.headers['x-tenant-id'];
if (headerTenantId) {
tenantId = parseInt(headerTenantId, 10);
}
if (!tenantId && req.user && req.user.tenantId) {
tenantId = req.user.tenantId;
}
if (tenantId) {
const tenant = await Tenant.findOne({
where: {
id: tenantId,
status: 'active',
isDeleted: 0
}
});
if (tenant) {
req.tenantId = tenantId;
req.tenant = tenant;
}
}
next();
} catch (error) {
console.error('可选租户中间件错误:', error);
next();
}
};
/**
* 系统管理员权限检查中间件
*/
const superAdminMiddleware = (req, res, next) => {
if (!req.user || req.user.userType !== 'super_admin') {
return res.status(403).json({
code: 403,
message: '需要系统管理员权限'
});
}
next();
};
module.exports = {
tenantContextMiddleware,
optionalTenantMiddleware,
superAdminMiddleware
};