131 lines
3.0 KiB
JavaScript
131 lines
3.0 KiB
JavaScript
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
|
||
};
|