axios前端加密通訊的處理

axios前端加密通訊的處理

今天談一談前段時間,項目中遇見的前端axios加解密的處理。

先談談項目前景,因為安全的要求,所以我們要把前端所有的請求都得加密與服務端應用進行通訊,當然服務端的響應也是加密的,前端也需要對應得解密。

一、攔截器InterceptorManager

遇見這個需求,或許從axios文檔中,我們第一時間想到的就是InterceptorManager。

axios.interceptors.request.use(req => {
  // todo 加密
})
axios.interceptors.response.use(rsp => {
  // todo 解密
})

但是現在需求升級了,我們要求前端根據服務端的響應狀態碼自動切換加密或者明文通迅。

我們再回過頭看看InterceptorManager還合適么?

當然這個需求在一般情況下是比較少見的,但是確實存在不是么?接下來我們看看方法2

二、代理axios.request方法。

可以實現,但是還是略為複雜。

import Axios from 'axios/lib/core/Axios'
import axiosBind from 'axios/lib/helpers/bind'
import axiosUtils from 'axios/lib/utils'

// todo 導入 加密的securityAxios, 正常的defaultAxios。
// todo 導入 全局變量isSecurity控制是否需要加密

async function requestProxy(...args) {
    if(isSecurity){
        return await securityAxios.request(...args)
    }
    return await defaultAxios.request(...args)
}
function createInstance(defaultConfig) {
    const context = new Axios(defaultConfig);
    Object.defineProperty(context, 'defaults', {
        get() {
            return isSecurity ? securityAxios.defaults : defaultAxios.defaults;
        },
    })
    context.request = requestProxy;

    var instance = axiosBind(requestProxy, context);
    axiosUtils.extend(instance, Axios.prototype, context);
    axiosUtils.extend(instance, context);

    return instance;
}

const axiosInstance = createInstance();
axiosInstance.axios = axiosInstance;

export default axiosInstance;

這種方式看看就好了,當時是半路接過來某項目選擇了這種方式簡單優化下。

三、包裝自定義的fetch方法


export function fetch(...args){
  if(isSecurity){
    return securityAxios(...args);
  }
  return defaultAxios(...args);
}

此方法相對上面的方法,實現更方便,但是如果項目中使用的是axios的實例去操作,則這種方式修改的地方太大了。

四、自定義Adapter

大概這種方式是最優解了。

import axios from 'axios'

export default ((defaultAdapter) => {
  function security(cfg){
    // todo 構建新的加密後的config;
    return newCfg;
  }
  function unsecurity(rsp){
    // todo 解密返回的加密串;
    return newRsp;
  }
  return function securityAdapter(config){
    const securityConfig = security(config)
    const resp = defaultAdapter(securityConfig)
    return unsecurity(resp)
  }
})(axios.default.adapter)

import securityAdapter from './securityAdapter'
const securityAdapter = axios.create({
  adapter: securityAdapter,
})
// todo

總結

以上幾種方式,都是我實際項目中,遇見的實現方式,或是自己的處理方式。

  • 方法一,不夠解藕,攔截器很容易過於複雜;
  • 方法二,過於繁所;
  • 方法三,需要修改現有的代碼;
  • 方法四,暫時來看是最合適的

需求繼續升級,如果,前端加密後,發現後端需要接收明文,切換後,需要重新請求,那麼哪種方式修改起來最方便呢?