MST

星途 面试题库

面试题:React路由传参时如何处理复杂对象并保证参数传递的安全性

在React应用中,使用React Router进行路由传参,需要从一个页面传递一个包含多个属性(如用户信息对象,包含姓名、年龄、地址等复杂结构)的对象到另一个页面。请阐述实现思路,并说明如何防止在参数传递过程中数据被篡改,确保安全性。
19.5万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 使用state进行传参
    • 在源页面,当使用Link组件或history.push方法时,将包含用户信息对象的状态数据作为state传递。例如:
    import React from'react';
    import { Link } from'react - router - dom';
    
    const userInfo = {
      name: '张三',
      age: 25,
      address: '北京市朝阳区'
    };
    
    const SourcePage = () => {
      return (
        <Link
          to={{
            pathname: '/targetPage',
            state: { userInfo }
          }}
        >
          跳转到目标页面
        </Link>
      );
    };
    
    export default SourcePage;
    
    • 在目标页面,通过location.state获取传递过来的数据。例如:
    import React from'react';
    import { useLocation } from'react - router - dom';
    
    const TargetPage = () => {
      const location = useLocation();
      const { userInfo } = location.state || {};
      return (
        <div>
          <p>姓名: {userInfo?.name}</p>
          <p>年龄: {userInfo?.age}</p>
          <p>地址: {userInfo?.address}</p>
        </div>
      );
    };
    
    export default TargetPage;
    
  2. 使用查询字符串传参
    • 首先将复杂的用户信息对象转换为字符串格式,例如使用JSON.stringify。在源页面构建查询字符串:
    import React from'react';
    import { Link } from'react - router - dom';
    
    const userInfo = {
      name: '张三',
      age: 25,
      address: '北京市朝阳区'
    };
    const userInfoStr = encodeURIComponent(JSON.stringify(userInfo));
    
    const SourcePage = () => {
      return (
        <Link to={`/targetPage?userInfo=${userInfoStr}`}>
          跳转到目标页面
        </Link>
      );
    };
    
    export default SourcePage;
    
    • 在目标页面,从location.search中获取查询字符串并解析:
    import React from'react';
    import { useLocation } from'react - router - dom';
    
    const TargetPage = () => {
      const location = useLocation();
      const urlParams = new URLSearchParams(location.search);
      const userInfoStr = urlParams.get('userInfo');
      const userInfo = userInfoStr? JSON.parse(decodeURIComponent(userInfoStr)) : {};
      return (
        <div>
          <p>姓名: {userInfo?.name}</p>
          <p>年龄: {userInfo?.age}</p>
          <p>地址: {userInfo?.address}</p>
        </div>
      );
    };
    
    export default TargetPage;
    

防止数据篡改确保安全性

  1. 使用HTTPS:确保应用部署在HTTPS协议上,这样可以防止中间人攻击,避免在传输过程中数据被拦截和篡改。
  2. 数据校验
    • 在目标页面接收到数据后,对数据进行严格的校验。例如,对于用户信息对象中的年龄,可以校验是否为数字且在合理范围内。
    const TargetPage = () => {
      const location = useLocation();
      const { userInfo } = location.state || {};
      if (userInfo) {
        if (typeof userInfo.age!== 'number' || userInfo.age < 0 || userInfo.age > 120) {
          // 处理异常数据,如提示错误或重置数据
          userInfo.age = null;
        }
      }
      return (
        <div>
          <p>姓名: {userInfo?.name}</p>
          <p>年龄: {userInfo?.age}</p>
          <p>地址: {userInfo?.address}</p>
        </div>
      );
    };
    
  3. 加密数据
    • 在源页面,对要传递的数据进行加密,例如使用加密库(如crypto - js)对用户信息对象进行加密。
    import CryptoJS from 'crypto - js';
    
    const userInfo = {
      name: '张三',
      age: 25,
      address: '北京市朝阳区'
    };
    const encryptedUserInfo = CryptoJS.AES.encrypt(JSON.stringify(userInfo), 'secretKey').toString();
    
    • 在目标页面,使用相同的密钥进行解密。
    import CryptoJS from 'crypto - js';
    
    const bytes = CryptoJS.AES.decrypt(encryptedUserInfo,'secretKey');
    const decryptedUserInfo = JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
    
  4. 签名验证
    • 在源页面,生成数据的签名。例如,结合加密库和哈希算法(如SHA - 256),对用户信息对象和一个密钥生成签名。
    import { createHash } from 'crypto';
    
    const userInfo = {
      name: '张三',
      age: 25,
      address: '北京市朝阳区'
    };
    const dataToSign = JSON.stringify(userInfo);
    const key ='secretKey';
    const hash = createHash('sha256');
    hash.update(dataToSign + key);
    const signature = hash.digest('hex');
    
    • 在目标页面,重新计算签名并与传递过来的签名进行比对,如果不一致则说明数据可能被篡改。
    const receivedSignature = '...';// 从传递数据中获取的签名
    const recalculatedHash = createHash('sha256');
    recalculatedHash.update(decryptedUserInfo + key);
    const recalculatedSignature = recalculatedHash.digest('hex');
    if (recalculatedSignature!== receivedSignature) {
      // 处理数据被篡改情况,如提示错误
    }