Uni-app网络请求AES加密解密实现

Uni-app 网络请求封装与 AES 加密解密实现

下面我将为你提供一个完整的 Uni-app 网络请求封装方案,包含 POST 请求的统一处理、请求参数和响应数据的 AES 加密解密。

1. 创建加密解密工具类

首先创建一个 crypto.js 文件用于处理 AES 加密解密:

// utils/crypto.js
import CryptoJS from 'crypto-js'

const key = CryptoJS.enc.Utf8.parse('1234567890abcdef') // 16位密钥
const iv = CryptoJS.enc.Utf8.parse('abcdef1234567890') // 16位初始向量

export default {
  // AES加密
  encrypt(data) {
    if (typeof data === 'object') {
      data = JSON.stringify(data)
    }
    const encrypted = CryptoJS.AES.encrypt(
      CryptoJS.enc.Utf8.parse(data),
      key,
      {
        iv: iv,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
      }
    )
    return encrypted.toString()
  },

  // AES解密
  decrypt(encrypted) {
    const decrypted = CryptoJS.AES.decrypt(encrypted, key, {
      iv: iv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    })
    return decrypted.toString(CryptoJS.enc.Utf8)
  }
}

2. 封装网络请求

创建一个 request.js 文件封装网络请求:

// utils/request.js
import crypto from './crypto.js'

// 请求基地址
const BASE_URL = 'https://your-api-domain.com/api'

// 统一请求方法
const request = (url, data = {}, method = 'POST') => {
  return new Promise((resolve, reject) => {
    // 加密请求数据
    const encryptedData = crypto.encrypt(data)
    
    uni.request({
      url: BASE_URL + url,
      method: method,
      data: {
        encrypted: encryptedData
      },
      header: {
        'Content-Type': 'application/json',
        'Authorization': uni.getStorageSync('token') || ''
      },
      success: (res) => {
        if (res.statusCode === 200) {
          try {
            // 解密响应数据
            const decrypted = crypto.decrypt(res.data.encrypted)
            const result = JSON.parse(decrypted)
            
            // 这里可以根据业务需求处理不同的状态码
            if (result.code === 200) {
              resolve(result.data)
            } else {
              // 处理业务错误
              uni.showToast({
                title: result.message || '请求失败',
                icon: 'none'
              })
              reject(result)
            }
          } catch (e) {
            console.error('解密或解析响应数据失败:', e)
            uni.showToast({
              title: '数据处理失败',
              icon: 'none'
            })
            reject(e)
          }
        } else {
          // HTTP状态码错误处理
          uni.showToast({
            title: `请求失败: ${res.statusCode}`,
            icon: 'none'
          })
          reject(res)
        }
      },
      fail: (err) => {
        uni.showToast({
          title: '网络连接失败',
          icon: 'none'
        })
        reject(err)
      }
    })
  })
}

// 封装POST请求
const post = (url, data) => {
  return request(url, data, 'POST')
}

export default {
  request,
  post
}

3. 使用示例

在页面或组件中使用封装好的请求:

import request from '@/utils/request.js'

export default {
  methods: {
    async fetchData() {
      try {
        const params = {
          page: 1,
          size: 10
        }
        const result = await request.post('/user/list', params)
        console.log('获取到的数据:', result)
        // 处理数据...
      } catch (error) {
        console.error('请求出错:', error)
      }
    },
    
    async login() {
      try {
        const res = await request.post('/auth/login', {
          username: 'admin',
          password: '123456'
        })
        console.log('登录成功:', res)
        // 保存token等操作...
      } catch (error) {
        console.error('登录失败:', error)
      }
    }
  }
}

4. 全局挂载(可选)

main.js 中全局挂载:

// main.js
import request from '@/utils/request.js'

Vue.prototype.$request = request

然后在任何地方都可以使用:

this.$request.post('/api/example', {param: 'value'})

5. 注意事项

  1. 密钥安全:实际项目中,密钥不应该直接写在代码中,应该通过更安全的方式获取
  2. 错误处理:根据实际业务需求调整错误处理逻辑
  3. 性能考虑:加密解密会增加一定的性能开销,对于大数据量要考虑性能影响
  4. HTTPS:确保生产环境使用HTTPS协议传输加密数据
  5. 密钥管理:定期更换密钥,并确保前后端密钥一致

6. 服务端配合

服务端也需要相应的解密和加密处理,以Node.js为例:

const CryptoJS = require('crypto-js')

const decryptData = (encrypted) => {
  const key = CryptoJS.enc.Utf8.parse('1234567890abcdef')
  const iv = CryptoJS.enc.Utf8.parse('abcdef1234567890')
  
  const decrypted = CryptoJS.AES.decrypt(encrypted, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })
  
  return JSON.parse(decrypted.toString(CryptoJS.enc.Utf8))
}

const encryptData = (data) => {
  const key = CryptoJS.enc.Utf8.parse('1234567890abcdef')
  const iv = CryptoJS.enc.Utf8.parse('abcdef1234567890')
  
  const encrypted = CryptoJS.AES.encrypt(
    CryptoJS.enc.Utf8.parse(JSON.stringify(data)),
    key,
    {
      iv: iv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    }
  )
  
  return encrypted.toString()
}

// Express中使用示例
app.post('/api/user/list', (req, res) => {
  try {
    const decrypted = decryptData(req.body.encrypted)
    console.log('解密后的请求参数:', decrypted)
    
    // 处理业务逻辑...
    const result = {
      code: 200,
      message: 'success',
      data: [] // 你的业务数据
    }
    
    // 加密响应
    res.send({
      encrypted: encryptData(result)
    })
  } catch (error) {
    console.error('处理请求出错:', error)
    res.status(500).send({
      encrypted: encryptData({
        code: 500,
        message: '服务器错误'
      })
    })
  }
})

这样,你就实现了一个完整的 Uni-app 网络请求封装,包含请求和响应的 AES 加密解密处理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值