面试题答案
一键面试安全机制
- 身份验证
- 基于Token的身份验证:
- 原理:用户登录成功后,服务器生成一个Token(通常是JWT,即JSON Web Token)。Token包含用户相关信息(如用户ID、用户名等)和签名。客户端在后续请求中将Token放在请求头(如
Authorization: Bearer <token>
)中。服务器收到请求后,验证Token的签名和有效性。 - 实现:使用
jsonwebtoken
库,安装:npm install jsonwebtoken
。生成Token示例代码:
- 原理:用户登录成功后,服务器生成一个Token(通常是JWT,即JSON Web Token)。Token包含用户相关信息(如用户ID、用户名等)和签名。客户端在后续请求中将Token放在请求头(如
- 基于Token的身份验证:
const jwt = require('jsonwebtoken');
const payload = { userId: 1, username: 'user1' };
const secret = 'your - secret - key';
const token = jwt.sign(payload, secret, { expiresIn: '1h' });
验证Token示例代码:
const jwt = require('jsonwebtoken');
const secret = 'your - secret - key';
const token = req.headers.authorization.split(' ')[1];
try {
const decoded = jwt.verify(token, secret);
// 验证成功,可获取用户信息decoded.userId等
} catch (err) {
// 验证失败
}
- OAuth 2.0:
- 原理:适用于第三方应用授权场景。用户授权第三方应用访问其在资源服务器上的资源。涉及授权服务器、资源服务器、客户端等角色。
- 实现:可使用
passport - oauth2
等相关库,根据不同的OAuth 2.0服务提供商(如Google、Facebook等)进行配置和集成。
- 授权
- 基于角色的访问控制(RBAC):
- 原理:定义不同的角色(如管理员、普通用户等),每个角色有不同的权限集合。用户被分配到特定角色,根据其角色决定对资源的访问权限。
- 实现:数据库中创建
roles
表存储角色信息,permissions
表存储权限信息,role_permissions
表关联角色和权限,users
表关联用户和角色。在API处理函数中,根据用户角色判断是否有权限访问资源。例如:
- 基于角色的访问控制(RBAC):
const userRole = getRoleFromToken(req.headers.authorization);
const requiredPermission = 'view - resource';
const hasPermission = checkPermission(userRole, requiredPermission);
if (!hasPermission) {
return res.status(403).send('Forbidden');
}
// 继续处理请求
- 防止常见Web攻击
- 防止SQL注入:
- 使用参数化查询:对于SQL数据库(如MySQL、PostgreSQL等),在Node.js中使用数据库驱动提供的参数化查询功能。例如,使用
mysql
库:
- 使用参数化查询:对于SQL数据库(如MySQL、PostgreSQL等),在Node.js中使用数据库驱动提供的参数化查询功能。例如,使用
- 防止SQL注入:
const mysql = require('mysql');
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'test'
});
const username = req.body.username;
const query = 'SELECT * FROM users WHERE username =?';
connection.query(query, [username], (error, results, fields) => {
if (error) throw error;
// 处理查询结果
});
- 防止XSS攻击:
- 输入验证和过滤:使用
DOMPurify
库对用户输入进行过滤。安装:npm install dompurify
。示例:
- 输入验证和过滤:使用
const DOMPurify = require('dompurify');
const cleanInput = DOMPurify.sanitize(req.body.input);
// 使用cleanInput,可防止XSS攻击
- **输出编码**:在将数据输出到HTML页面时,对特殊字符进行编码。例如,在使用`ejs`模板引擎时,`ejs`会自动对输出内容进行HTML转义。
高可靠性
- 容错处理
- 错误处理中间件:在Express应用中,创建全局错误处理中间件。例如:
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('Something went wrong!');
});
- 异步操作错误处理:在Promise和
async/await
中,使用.catch()
处理Promise拒绝或try - catch
捕获async
函数中的错误。例如:
async function getData() {
try {
const response = await fetch('https://example.com/api');
const data = await response.json();
return data;
} catch (error) {
console.error('Error fetching data:', error);
return null;
}
}
- 负载均衡
- 硬件负载均衡器:如F5 Big - IP等设备,通过在网络层对流量进行分发,将客户端请求均衡地分配到多个后端Node.js服务器上。
- 软件负载均衡器:
- Nginx:安装Nginx后,配置反向代理和负载均衡。例如,在
nginx.conf
文件中:
- Nginx:安装Nginx后,配置反向代理和负载均衡。例如,在
http {
upstream node_backend {
server 192.168.1.10:3000;
server 192.168.1.11:3000;
}
server {
listen 80;
location / {
proxy_pass http://node_backend;
}
}
}
- **HAProxy**:同样可作为反向代理和负载均衡器,通过配置文件定义后端服务器池和负载均衡策略。例如:
frontend http - in
bind *:80
default_backend node - servers
backend node - servers
balance roundrobin
server node1 192.168.1.10:3000 check
server node2 192.168.1.11:3000 check
- 灾难恢复
- 数据备份与恢复:
- 定期备份数据库:使用数据库自带的备份工具,如MySQL的
mysqldump
命令进行全量或增量备份。可通过脚本定时执行备份任务,将备份文件存储在远程存储(如Amazon S3等)。 - 数据恢复:在发生灾难时,使用备份文件恢复数据库。例如,对于MySQL,使用
mysql
命令导入备份文件。
- 定期备份数据库:使用数据库自带的备份工具,如MySQL的
- 多数据中心部署:将Node.js应用部署在多个地理上分散的数据中心。当一个数据中心出现故障时,流量可切换到其他数据中心。可通过全局负载均衡器(如Amazon Route 53)实现跨数据中心的流量管理。
- 数据备份与恢复: