MST

星途 面试题库

面试题:Node.js RESTful API 安全架构设计

设计一个 Node.js RESTful API 的安全架构,要涵盖身份验证、授权、防止常见攻击(如 SQL 注入、XSS)等方面,详细描述每个安全机制的实现思路以及可能用到的中间件或工具。
22.5万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

身份验证

  1. 实现思路
    • 基于 Token:用户登录时,服务器验证用户凭据(如用户名和密码)。如果验证成功,服务器生成一个包含用户标识等信息的 Token(通常是 JWT,JSON Web Token)。客户端在后续请求中将 Token 放在请求头(如 Authorization: Bearer <token>)中发送。服务器在收到请求时,验证 Token 的有效性,若有效则允许请求继续处理。
    • Session - Cookie:用户登录成功后,服务器创建一个 Session 并将 Session ID 通过 Cookie 发送给客户端。客户端后续请求会带上这个 Cookie,服务器通过 Session ID 查找对应的 Session 信息来验证用户身份。
  2. 可能用到的中间件或工具
    • jsonwebtoken:用于生成、验证 JWT 的库。例如,生成 Token:
    const jwt = require('jsonwebtoken');
    const payload = { userId: 123 };
    const token = jwt.sign(payload, 'your - secret - key', { expiresIn: '1h' });
    
    验证 Token:
    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
    }));
    

授权

  1. 实现思路
    • 基于角色的访问控制(RBAC):定义不同的角色(如管理员、普通用户等),每个角色具有不同的权限集合。当用户登录并通过身份验证后,服务器根据用户的角色来判断其是否有权限执行某个操作。例如,只有管理员角色可以执行删除用户的操作。
    • 基于资源的访问控制(RBAC):针对每个资源(如特定的 API 端点、数据库记录等)定义权限。用户的权限与特定资源相关联,在请求访问资源时,服务器检查用户对该资源的权限。
  2. 可能用到的中间件或工具
    • 可以自定义中间件
    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 注入

  1. 实现思路
    • 参数化查询:在执行 SQL 语句时,使用参数化查询而不是直接拼接 SQL 字符串。这样数据库会将参数作为数据处理,而不是 SQL 代码的一部分,从而防止恶意 SQL 代码的注入。
    • 输入验证:对用户输入的数据进行严格验证,确保数据符合预期的格式和类型。例如,如果期望是数字,验证输入是否为数字。
  2. 可能用到的中间件或工具
    • 对于 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);
    });
    

防止 XSS(跨站脚本攻击)

  1. 实现思路
    • 输入过滤:对用户输入的数据进行过滤,去除或转义危险的字符和标签。例如,将 <script> 标签转义为 &lt;script&gt;
    • 输出编码:在将数据输出到前端页面时,对数据进行编码,确保任何用户输入的数据都不会被浏览器解析为可执行的脚本。
  2. 可能用到的中间件或工具
    • 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());