Vue浏览器链接与接口参数实现加密过程详解

 更新时间:2022年12月21日 14:08:36   作者:仙人掌上的刺猬  
这篇文章主要介绍了Vue浏览器链接与接口参数实现加密过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

场景

由于项目创建之前后端设计不合理,导致详情页链接参数id为顺序序数(例:1,2,3…等等),安全系数非常低(虽然我们前端做了菜单权限、按钮权限、Api权限等等),现在要前端解决下浏览器链接/接口参数实现加密🤬🤬

注:前端链接加密与接口参数加密(get请求)类似

思路过程

1、设计格式

项目正常链接为

contract/draft/contract-draft-detail?id=26197&type=news&key=1667198460529

我们最终需要base64加密成这种(如果不想base64加密也可换成其他加密方式 👇

如:RSA加密、AES加密、MD5加密、SHA256加密以及国密)

contract/draft/contract-draft-detail?__params=eyJpZCI6MjYxOTcsInR5cGUiOiJuZXciLCJrZXkiOjE2NjcxOTg0NjA1Mjl9

要想将参数加密,我这里设计的是,将所有参数以对象的形式进行加密,如图

正常参数格式: `id=26197&type=news&key=1667198460529`,
转化成对象:  {
    id: 26197,
    type: 'news',
    key: '1667198460529'
}

正常情况下,可直接 $route.query 获取参数对象,或 window.location.search 格式化获取,格式化函数见下方,

// URL参数转成对象
export function urlPasseObj(url = '', isUrl) {
  const result = url.split('?')[isUrl ? 1 : 0]
  if (!result) {
    return {}
  }
  const list = result.split('&')
  const obj = {}
  list.map(item => {
    if (item) {
      const arr = item.split('=')
      const value = arr[1]
      obj[arr[0]] = value === undefined ? '' : value
    }
  })
  return obj
}

加密后都放到一个参数中,这里我命名为 __params

2、加/解密方法实现

这里要注意的是base64加密正常是字符串(String类型)进行加密,对对象(Object)进行加密,需要通过JSON.parse进行转义成String类型

代码如下

/**
 * base64(解密)
 * @param {String} str 跳转参数为base64字符串
 * @returns
 */
export const decryptBase64 = function(str) {
  // 添加decodeURIComponent解决其他特殊字符,如等号(=)会转成%3D,导致base64解密失败
  const decryptQuery = str ? JSON.parse(base64.decode(decodeURIComponent(str))) : {}
  return decryptQuery
}
/**
 * base64(加密)
 * @param {Object || String} param 跳转参数可以为对象或路径字符串
 * @returns
 */
export const encryptBase64 = function(param) {
  const encryptStr = base64.encode(JSON.stringify(param)) || ''
  return encryptStr
}

3、加密处理位置

$route.push跳转处

通常咱们在Vue文件下通过 $router.push 进行路由跳转,跳转时需要对参数进行加密处理,这样跳转后的链接参数才会以加密的形式进行呈现。有些人可能觉得单独写一个方法进行路由跳转,不从 $router.push跳转了,但是我这个项目是中后期项目了,担心后面其他前端同事不熟悉项目,不知道加密这回事,所以我就在Router.prototype.push 直接进行修改了

代码如下:

// 在router/index.js中修改
const originalPush = Router.prototype.push
Router.prototype.push = function push(location, onResolve, onReject) {
  if (onResolve || onReject) return originalPush.call(this, location, onResolve, onReject)
  // 解决空对象中含有{__ob__: Observer},深拷贝
  let newLocation = deepCopy(location)
  if (newLocation?.query && Object.keys(newLocation.query).length !== 0) {
    newLocation = location.query?.__params ? location : {
      ...location,
      query: {
        __params: encryptBase64(newLocation.query)
      }
    }
  }
  return originalPush.call(this, newLocation).catch(err => err)
}

路由拦截请求(处理get请求参数)

在路由拦截器请求时,通常会处理一些逻辑。将token放入携带的请求头中等等,所以咱们要将get请求中参数在此处进行处理。get请求的参数会和浏览器链接一样,在url中,例:

所以我们处理方式与浏览器链接参数处理方式一样,具体实现方法如下,

request.interceptors.request.use(config => {
   if (config.method === 'get') {
    config.data = true
    // 判断是否有携带参数
    const isHash = config.url.includes('?')
    if (isHash) {
      // 将url上的参数调整到params中,然后调整清除url上的参数
      // urlPasseObj方法在上方
      const urlParam = urlPasseObj(config.url, true)
      config.params = config.params ? { ...config.params, ...urlParam } : urlParam
      config.url = config.url.split('?')[0]
    }
    if (config.params) {
      config.params = {
        __params: encryptBase64(config.params)
      }
    }
  }
  return config
}, errorHandler)

注:在无参数时,config中不存在params属性,所以要初始化一下

4、解密处理位置

在App.vue中初始化一个变量来代替$router.query

watch: {
   '$route.query': {
     immediate: true,
     deep: true,
     handler(val) {
       if (val.__params) {
         const newQuery = decryptBase64(val?.__params)
         // 在vue原型上定义一个
         Vue.prototype.$route_query = newQuery
         return
       }
       Vue.prototype.$route_query = val || {}
     }
   }
 }

然后咱们只能将整个项目用到$route.query的地方,全局替换下了~~最后使用方式见下方

created() {

this.id = this.$route_query.id

this.getSetTing()

},

小结

有可能会有人想问,为什么不把 $router.push也替换成全局,而只把 $route.query用一个变量替换?

因为如果不将$route.query替换成另一个变量( $route_query ),没办法获取到解密的参数(除非一个文件一个文件看着改,而不可以全局替换改)。我当时尝试在路由守卫和路由钩子函数里想要处理 $route.query中的参数,但是发现这个是一个只读的属性,不可以中途改变值。

不把 $router.push也替换成全局,是为了方便后续其他同事在开发时,不需要注意加密参数了,push自动格式化参数成加密。

到此这篇关于Vue浏览器链接与接口参数实现加密过程详解的文章就介绍到这了,更多相关Vue链接加密内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用Vue开发登录页面的完整指南

    使用Vue开发登录页面的完整指南

    Vue.js 是一个流行的前端JavaScript框架,用于构建用户界面,在这个"vue网页登录界面"的示例中,我们探讨的是如何使用Vue.js创建一个简单的登录页面,感兴趣的小伙伴跟着小编一起来看看吧
    2025-04-04
  • vue-drag-resize与输入框/文本框冲突问题

    vue-drag-resize与输入框/文本框冲突问题

    这篇文章主要介绍了vue-drag-resize与输入框/文本框冲突问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • 解决在Vue中使用axios用form表单出现的问题

    解决在Vue中使用axios用form表单出现的问题

    今天小编就为大家分享一篇解决在Vue中使用axios用form表单出现的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-10-10
  • 详解如何用模块化的方式写vuejs

    详解如何用模块化的方式写vuejs

    这篇文章主要介绍了详解如何用模块化的方式写vuejs,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • vue 行为验证码之滑动验证AJ-Captcha使用详解

    vue 行为验证码之滑动验证AJ-Captcha使用详解

    这篇文章主要介绍了vue 行为验证码之滑动验证AJ-Captcha使用详解,AJ-Captcha不需要npm安装,只需要将组件 verifition复制到所使用的components目录下,本文给大家详细讲解,需要的朋友可以参考下
    2023-05-05
  • vue3中addEventListener的用法详解

    vue3中addEventListener的用法详解

    vue3中定义全局指令时,往往会碰到一个问题:事件无法解绑,为什么会这样,因为通常在指令的mounted钩子中绑定事件,事件处理函数也定义在mounted中,本文讲给大家讲讲vue3中addEventListener的妙用,需要的朋友可以参考下
    2023-08-08
  • antd Form组件方法getFieldsValue获取自定义组件的值操作

    antd Form组件方法getFieldsValue获取自定义组件的值操作

    这篇文章主要介绍了antd Form组件方法getFieldsValue获取自定义组件的值操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • Vue使用video标签实现视频播放

    Vue使用video标签实现视频播放

    这篇文章主要为大家详细介绍了Vue使用video标签实现视频播放,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • 基于Vue实现微前端的示例代码

    基于Vue实现微前端的示例代码

    这篇文章主要介绍了基于Vue实现微前端的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • Vue登录功能实现全套详解(含封装axios)

    Vue登录功能实现全套详解(含封装axios)

    登录功能对于前端刚入门不久的同学来说较为困难,下面这篇文章主要给大家介绍了关于Vue登录功能实现(含封装axios)的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-12-12

最新评论