MST

星途 面试题库

面试题:Node.js前后端分离架构下的数据交互安全与可靠性设计

在一个涉及金融交易的Node.js前后端分离系统中,数据交互的安全性和可靠性至关重要。请详细说明你会如何设计数据交互流程以确保数据的保密性、完整性和可用性,例如如何防止中间人攻击、数据篡改,以及在网络不稳定情况下保证交易数据的准确传输和处理。要求结合Node.js相关技术和安全机制进行阐述。
34.8万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

1. 数据保密性

  • HTTPS 协议:在 Node.js 后端,使用 Express 等框架搭建服务器时,配置 HTTPS。通过申请 SSL/TLS 证书,使服务器与客户端之间建立加密连接。例如,使用 https 模块结合证书文件来创建 HTTPS 服务器:
const https = require('https');
const fs = require('fs');
const app = require('express')();

const options = {
  key: fs.readFileSync('privatekey.pem'),
  cert: fs.readFileSync('certificate.pem')
};

https.createServer(options, app).listen(443, () => {
  console.log('HTTPS server running on port 443');
});
  • 数据加密:在数据传输前,对敏感数据(如交易金额、用户账号等)进行加密。在 Node.js 中,可以使用 crypto 模块。例如,使用 AES 加密算法:
const crypto = require('crypto');
const algorithm = 'aes - 256 - cbc';
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);

function encrypt(text) {
  const cipher = crypto.createCipheriv(algorithm, key, iv);
  let encrypted = cipher.update(text, 'utf8', 'hex');
  encrypted += cipher.final('hex');
  return encrypted;
}

2. 数据完整性

  • 消息认证码(MAC):在 Node.js 中,使用 crypto 模块生成和验证 MAC。例如,使用 HMAC - SHA256:
const crypto = require('crypto');
const message = '交易数据';
const key = '秘密密钥';

function generateMAC(message, key) {
  const hmac = crypto.createHmac('sha256', key);
  hmac.update(message);
  return hmac.digest('hex');
}

const mac = generateMAC(message, key);
// 接收方验证 MAC
function verifyMAC(message, key, receivedMAC) {
  const calculatedMAC = generateMAC(message, key);
  return calculatedMAC === receivedMAC;
}
  • 数字签名:对于重要交易数据,使用私钥对数据进行签名,接收方使用公钥验证签名。Node.js 中可以使用 crypto 模块实现。例如:
const crypto = require('crypto');
const privateKey = fs.readFileSync('private_key.pem');
const publicKey = fs.readFileSync('public_key.pem');

function signData(data) {
  const sign = crypto.createSign('RSA - SHA256');
  sign.update(data);
  return sign.sign(privateKey, 'hex');
}

function verifySignature(data, signature) {
  const verify = crypto.createVerify('RSA - SHA256');
  verify.update(data);
  return verify.verify(publicKey, signature, 'hex');
}

3. 防止中间人攻击

  • 证书验证:在客户端(前端使用 Node.js 的 Electron 等框架时),确保验证服务器发送的 SSL/TLS 证书的有效性。在浏览器环境中,浏览器会自动进行证书验证,但在自定义 Node.js 客户端中,需要手动实现。例如,在 https 请求中设置 rejectUnauthorized: true(默认值)来拒绝无效证书的连接:
const https = require('https');
https.get({
  host: 'example.com',
  port: 443,
  path: '/',
  rejectUnauthorized: true
}, (res) => {
  // 处理响应
});
  • 公钥固定:在客户端存储服务器的公钥,每次连接时验证服务器的公钥是否与存储的一致。这可以防止中间人替换服务器的公钥。

4. 网络不稳定情况下保证交易数据准确传输和处理

  • 重试机制:在客户端,使用 axios 等 HTTP 库时,设置重试逻辑。例如,使用 axios - retry 库:
const axios = require('axios');
const AxiosRetry = require('axios - retry');

AxiosRetry(axios, {
  retries: 3,
  retryCondition: (error) => {
    return error.response && [500, 502, 503, 504].includes(error.response.status);
  }
});

axios.post('/transaction', { amount: 100 })
 .then(response => {
    // 处理成功响应
  })
 .catch(error => {
    // 处理错误
  });
  • 队列与持久化:在后端,使用消息队列(如 RabbitMQ、Kafka 等)结合 Node.js 的相关客户端库。将交易数据发送到队列中,确保即使网络不稳定,数据也不会丢失。同时,对交易数据进行持久化存储(如使用 MongoDB、MySQL 等数据库),以便在网络恢复后能够准确处理。例如,使用 amqplib 连接 RabbitMQ:
const amqp = require('amqplib');

async function sendTransactionToQueue(transaction) {
  const connection = await amqp.connect('amqp://localhost');
  const channel = await connection.createChannel();
  const queue = 'transactions';
  await channel.assertQueue(queue);
  channel.sendToQueue(queue, Buffer.from(JSON.stringify(transaction)));
  console.log('Transaction sent to queue');
  await channel.close();
  await connection.close();
}
  • 幂等性设计:在后端 API 设计上,确保交易处理接口具有幂等性。即多次调用相同的接口,对于相同的输入,产生的结果是一致的。例如,在处理支付交易时,通过检查交易状态来避免重复扣款。如果接收到重复的交易请求,先查询数据库中该交易的状态,如果已经处理成功,则直接返回成功响应。