MST

星途 面试题库

面试题:Vue 前端与后端 API 交互的安全设计与实践

在 Vue 应用和后端 API 交互过程中,面临着诸如 CSRF、XSS、SQL 注入等安全威胁。请详细阐述你会采取哪些前端和后端协同的安全措施来保障交互的安全性,并结合 Vue 的特性说明如何在代码层面实现这些安全机制。
33.3万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

前端安全措施

  1. CSRF(跨站请求伪造)
    • 措施:在前端,每次请求时带上 CSRF Token。在 Vue 项目中,可以在创建 Axios 实例时全局设置,将 Token 放在请求头中。例如:
    import axios from 'axios';
    const csrfToken = document.head.querySelector('meta[name="csrf-token"]').content;
    const instance = axios.create({
      headers: {
        'X - CSRF - Token': csrfToken
      }
    });
    export default instance;
    
  2. XSS(跨站脚本攻击)
    • 措施
      • 输入过滤:对用户输入的数据进行严格的过滤,去除可能包含恶意脚本的字符。在 Vue 组件中,可以使用 computed 属性对输入数据进行过滤处理。例如:
      <template>
        <div>
          <input v - model="inputValue">
          <p>{{filteredValue}}</p>
        </div>
      </template>
      <script>
      export default {
        data() {
          return {
            inputValue: ''
          };
        },
        computed: {
          filteredValue() {
            // 简单过滤示例,去除 <script> 标签
            return this.inputValue.replace(/<script.*?>.*?<\/script>/gi, '');
          }
        }
      };
      </script>
      
      • 输出编码:使用 Vue 的内置指令如 v - html 时要谨慎,对需要动态插入 HTML 的内容进行编码。例如:
      <template>
        <div v - html="encodedContent"></div>
      </template>
      <script>
      import { DOMPurify } from 'dompurify';
      export default {
        data() {
          return {
            originalContent: '<script>alert("XSS")</script>',
            encodedContent: ''
          };
        },
        created() {
          this.encodedContent = DOMPurify.sanitize(this.originalContent);
        }
      };
      </script>
      

后端安全措施

  1. CSRF
    • 措施:后端验证前端传来的 CSRF Token。以 Node.js 为例,使用 Express 框架,在中间件中验证 Token:
    const express = require('express');
    const app = express();
    app.use((req, res, next) => {
      const csrfToken = req.headers['x - csrf - token'];
      // 验证逻辑,假设从 session 中获取正确的 Token
      const expectedToken = req.session.csrfToken;
      if (csrfToken === expectedToken) {
        next();
      } else {
        res.status(403).send('Forbidden');
      }
    });
    
  2. XSS
    • 措施:后端同样要对接收的数据进行过滤和验证,防止恶意脚本存入数据库。例如在 Python 的 Django 框架中,可以使用内置的 clean 方法对表单数据进行清理:
    from django import forms
    class MyForm(forms.Form):
      content = forms.CharField()
      def clean_content(self):
        data = self.cleaned_data['content']
        # 简单过滤示例,去除 <script> 标签
        import re
        return re.sub(r'<script.*?>.*?<\/script>', '', data)
    
  3. SQL 注入
    • 措施:使用参数化查询或 ORM(对象关系映射)。以 Java 为例,使用 JDBC 时采用参数化查询:
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    public class UserDao {
      public User findUserByName(String name) {
        String sql = "SELECT * FROM users WHERE name =?";
        try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
          pstmt.setString(1, name);
          try (ResultSet rs = pstmt.executeQuery()) {
            if (rs.next()) {
              // 创建 User 对象并返回
            }
          }
        } catch (SQLException e) {
          e.printStackTrace();
        }
        return null;
      }
    }
    
    若使用 ORM,如 Hibernate,它会自动处理 SQL 注入问题,开发者无需手动编写复杂的 SQL 语句,而是通过对象操作数据库。例如:
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.Transaction;
    import org.hibernate.cfg.Configuration;
    public class UserService {
      public User findUserByName(String name) {
        SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
        Session session = sessionFactory.openSession();
        Transaction tx = session.beginTransaction();
        User user = session.createQuery("FROM User WHERE name = :name", User.class)
           .setParameter("name", name)
           .uniqueResult();
        tx.commit();
        session.close();
        return user;
      }
    }