面试题答案
一键面试身份验证
- 实现思路:
- 基于 Token:用户登录时,服务器验证用户凭据(如用户名和密码)。如果验证成功,服务器生成一个包含用户标识等信息的 Token(通常是 JWT,JSON Web Token)。客户端在后续请求中将 Token 放在请求头(如
Authorization: Bearer <token>
)中发送。服务器在收到请求时,验证 Token 的有效性,若有效则允许请求继续处理。 - Session - Cookie:用户登录成功后,服务器创建一个 Session 并将 Session ID 通过 Cookie 发送给客户端。客户端后续请求会带上这个 Cookie,服务器通过 Session ID 查找对应的 Session 信息来验证用户身份。
- 基于 Token:用户登录时,服务器验证用户凭据(如用户名和密码)。如果验证成功,服务器生成一个包含用户标识等信息的 Token(通常是 JWT,JSON Web Token)。客户端在后续请求中将 Token 放在请求头(如
- 可能用到的中间件或工具:
- jsonwebtoken:用于生成、验证 JWT 的库。例如,生成 Token:
验证 Token:const jwt = require('jsonwebtoken'); const payload = { userId: 123 }; const token = jwt.sign(payload, 'your - secret - key', { expiresIn: '1h' });
const jwt = require('jsonwebtoken'); app.use((req, res, next) => { const token = req.headers['authorization']; if (!token) return res.status(401).send('Access denied. No token provided.'); try { const decoded = jwt.verify(token.replace('Bearer ', ''), 'your - secret - key'); req.user = decoded; next(); } catch (error) { res.status(400).send('Invalid token.'); } });
- express - session:用于实现 Session - Cookie 机制的 Express 中间件。
const express = require('express'); const session = require('express - session'); const app = express(); app.use(session({ secret: 'your - secret - key', resave: false, saveUninitialized: true }));
授权
- 实现思路:
- 基于角色的访问控制(RBAC):定义不同的角色(如管理员、普通用户等),每个角色具有不同的权限集合。当用户登录并通过身份验证后,服务器根据用户的角色来判断其是否有权限执行某个操作。例如,只有管理员角色可以执行删除用户的操作。
- 基于资源的访问控制(RBAC):针对每个资源(如特定的 API 端点、数据库记录等)定义权限。用户的权限与特定资源相关联,在请求访问资源时,服务器检查用户对该资源的权限。
- 可能用到的中间件或工具:
- 可以自定义中间件:
const isAdmin = (req, res, next) => { if (req.user.role === 'admin') { next(); } else { res.status(403).send('Forbidden'); } }; app.get('/admin - only - route', isAdmin, (req, res) => { res.send('This is an admin - only route'); });
防止 SQL 注入
- 实现思路:
- 参数化查询:在执行 SQL 语句时,使用参数化查询而不是直接拼接 SQL 字符串。这样数据库会将参数作为数据处理,而不是 SQL 代码的一部分,从而防止恶意 SQL 代码的注入。
- 输入验证:对用户输入的数据进行严格验证,确保数据符合预期的格式和类型。例如,如果期望是数字,验证输入是否为数字。
- 可能用到的中间件或工具:
- 对于 MySQL:使用
mysql2
库时可以进行参数化查询。
const mysql = require('mysql2'); 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], (err, results) => { if (err) throw err; console.log(results); });
- 对于 PostgreSQL:使用
pg
库进行参数化查询。
const { Pool } = require('pg'); const pool = new Pool({ user: 'user', host: 'localhost', database: 'test', password: 'password', port: 5432 }); const username = req.body.username; const query = 'SELECT * FROM users WHERE username = $1'; pool.query(query, [username], (err, results) => { if (err) throw err; console.log(results.rows); });
- 对于 MySQL:使用
防止 XSS(跨站脚本攻击)
- 实现思路:
- 输入过滤:对用户输入的数据进行过滤,去除或转义危险的字符和标签。例如,将
<script>
标签转义为<script>
。 - 输出编码:在将数据输出到前端页面时,对数据进行编码,确保任何用户输入的数据都不会被浏览器解析为可执行的脚本。
- 输入过滤:对用户输入的数据进行过滤,去除或转义危险的字符和标签。例如,将
- 可能用到的中间件或工具:
- DOMPurify:一个用于清理 HTML 输入,防止 XSS 的库。
const DOMPurify = require('dompurify'); const dirty = req.body.input; const clean = DOMPurify.sanitize(dirty);
- 在 Express 中,可以使用
helmet
中间件:它可以设置各种 HTTP 头来增强安全性,包括防止 XSS 的Content - Security - Policy
头。
const express = require('express'); const helmet = require('helmet'); const app = express(); app.use(helmet());