You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

单数据库下多站点(WS1/WS2)的身份认证与安全配置咨询

Hey there! Let's break down your problem step by step—this is a super common scenario when building multiple related sites, so we’ve got solid patterns to balance shared data, isolation, and security.

Core Principle: Share Public Data, Isolate Auth/User Data

The key here is to keep your common information accessible to both sites while walling off user accounts, sessions, and permissions completely. You don’t need to overcomplicate things with separate databases or full framework deployments right away.

1. Database Architecture: Split Collections, Not Databases (For Now)

Instead of creating two separate ArangoDB instances, use isolated collections within a single database (you can split into separate databases later if needed for compliance or scale):

  • Shared Collections: Create collections like shared_articles, public_products, or common_settings for data both sites need access to.
  • Site-Specific Collections: For each site, create dedicated collections for users and permissions, e.g.:
    • ws1_users + ws1_permissions
    • ws2_users + ws2_permissions
      This approach avoids duplicate data, keeps queries simple, and prevents accidental cross-site data leaks. If you later need full database-level isolation, moving these collections to separate databases is straightforward.

2. Express Deployment: One Instance with Isolated Logic

You don’t need to deploy a separate Express framework for each Nginx server block. Two clean options:

Option A: Single App with Site Identification Middleware

Add a middleware at the top of your Express app to tag requests with the site ID, then use that tag to route to the right auth/data logic:

// Identify the site from the request hostname
app.use((req, res, next) => {
  const validSites = {
    'ws1.yourdomain.com': 'ws1',
    'ws2.yourdomain.com': 'ws2'
  };
  req.siteId = validSites[req.hostname];
  
  // Reject requests for unknown domains
  if (!req.siteId) {
    return res.status(403).send('Invalid site');
  }
  next();
});

// Example login route that uses the site ID
app.post('/api/login', async (req, res) => {
  // Query the site-specific user collection
  const user = await arango.db.collection(`${req.siteId}_users`).findOne({
    email: req.body.email
  });
  
  // Validate credentials, create session, etc.—all tied to ws1/ws2
});

Option B: Mounted Sub-Apps for Clean Isolation

If you want stricter code separation, create two Express sub-apps for each site and mount them based on the hostname:

const ws1App = express();
const ws2App = express();

// Configure ws1-specific auth middleware and routes
ws1App.use(ws1AuthMiddleware);
ws1App.get('/api/profile', ws1ProfileRoute);

// Configure ws2-specific auth middleware and routes
ws2App.use(ws2AuthMiddleware);
ws2App.get('/api/profile', ws2ProfileRoute);

// Main app routes requests to the correct sub-app
app.use((req, res, next) => {
  if (req.hostname === 'ws1.yourdomain.com') {
    ws1App(req, res, next);
  } else if (req.hostname === 'ws2.yourdomain.com') {
    ws2App(req, res, next);
  } else {
    res.status(403).send('Invalid site');
  }
});

Both options let you share common code (like shared data queries) while keeping auth logic isolated.

3. Security Measures to Block Cross-Site Access

To ensure users from one site can’t access the other:

  • Isolate Sessions: Use unique cookie names for each site (e.g., ws1_session_id and ws2_session_id) and set the domain cookie attribute to the respective site’s domain. For JWT, add a siteId claim to the token and validate it on every request—reject tokens where the siteId doesn’t match the current request’s site.
  • Strict Host Validation: In Nginx, add a check in each server block to reject requests with mismatched host headers:
    # For WS1 server block
    if ($host != 'ws1.yourdomain.com') {
      return 444; # Close connection immediately
    }
    
  • Bind Permissions to Site ID: When checking user permissions, always filter by the current siteId—never fetch permissions without it. For example, don’t just query permissions by userId; query by userId AND siteId.
  • Hardened Headers: Add security headers in Nginx to prevent cross-site exploits:
    add_header X-Frame-Options SAMEORIGIN;
    add_header Content-Security-Policy "default-src 'self'";
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
    

4. Best Practices to Keep Things Scalable

  • Start with Collections, Split Databases Later: Using isolated collections is simpler initially. Only split into separate databases if you hit compliance requirements, performance limits, or need complete data separation.
  • Share Common Utilities: Create a shared module for querying public data, so you don’t duplicate code across site-specific routes.
  • Test Cross-Site Scenarios: Intentionally try to use a WS1 user’s session on WS2, or query WS2’s user data from WS1—make sure these requests are rejected.
  • Log with Site ID: Include the siteId in all logs to easily debug issues across both sites.

Hope this gives you a clear path forward! Let me know if you need deeper details on any of these steps.

内容的提问来源于stack exchange,提问作者user7552709

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:36:59