加密后端接口,接收参数。。。前端信息安全处理
为什么要编码?
由于一些网络通信协议的限制, 或为了信息加密, 我们需要将原始信息转换为base64编码,然后才能进行传输.例如,发送某些内容 ASCII 控制字符在代码表中0-31之间的数据。
window.btoa 字符串 base64编码(注意中文不能编码); winodw.atob 对 base64字符串 解码(包含中文的) base64编码,不能正确解码);
AES 加密 —安装:
npm install crypto-js
例子使用:
aes加密: crypto.js
import CryptoJS from "crypto-js"; let CryptoJSKey = '0f90023fc9ae101e' //16位
自定义,与后端配置 const key = CryptoJS.enc.Utf8.parse(CryptoJSKey); const iv = CryptoJS.enc.Utf8.parse(CryptoJSKey); //AES加密传参 (封装) Encrypt(word) { let srcs = CryptoJS.enc.Utf8.parse(word);///需要加密的内容 // let encrypted = CryptoJS.AES.encrypt(srcs, key, { // iv: iv, // mode: CryptoJS.mode.CBC, // padding: CryptoJS.pad.Pkcs7 // }); if (typeof word == "string") { const srcs = CryptoJS.enc.Utf8.parse(word); encrypted = CryptoJS.AES.encrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); } else if (typeof word == "object") { //对象格式的转成json字符串 const data = JSON.stringify(word); const srcs = CryptoJS.enc.Utf8.parse(data); encrypted = CryptoJS.AES.encrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); } return encrypted.ciphertext.toString() },
// aes解密
decrypt(word) {
const encryptedHexStr = CryptoJS.enc.Hex.parse(word);
const srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
const decrypt = CryptoJS.AES.decrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
return decryptedStr.toString();
}
};
//在发送方和接收方共享机密密钥的前提下,HMAC 可用于确定通过不安全信道发送的消息是否已被篡改。
//发送方计算原始数据的哈希值,并将原始数据和哈希值放在一个消息中同时传送。
//接收方重新计算所接收消息的哈希值,并检查计算所得的 HMAC 是否与传送的 HMAC 匹配。
//因为更改消息和重新生成正确的哈希值需要密钥,所以对数据或哈希值的任何更改都会导致不匹配。
//因此,如果原始的哈希值与计算得出的哈希值相匹配,则消息通过身份验证。
//MD5(消息摘要算法 5)是 RSA Laboratories 开发的加密哈希算法。HMACMD5 接受任何大小的密钥,并生成长度为 128 位的哈希序列。
// HmacMD5加密
HMACShaEncrypt(word) {
let key = CryptoJSKey;
return CryptoJS.HmacMD5(word, key).toString().toUpperCase()
},
//时间,按需求传给后端
getTimeStamp(time) {
let y = time.getFullYear()
let m = time.getMonth() + 1
let d = time.getDate()
let h = time.getHours()
let min = time.getMinutes()
let s = time.getSeconds()
return y + (m > 9 ? m : "0" + m) + (d > 9 ? d : "0" + d) + (h > 9 ? h : "0" + h) + (min > 9 ? min : "0" + min) + (s > 9 ? s : "0" + s)
},
使用
封装axios
//axios.js 文件
import axios from 'axios'
import crypto from "../crypto"
// 对响应参数处理,如根据状态码提示相对应错误提示,或者token失效处理重新登录处理等操作
axios.interceptors.response.use(function (response) {
// Any status code that lie within the range of 2xx cause this function to trigger
// Do something with response data
const status = Number(res.status)//状态码
return response;
}, function (error) {
// Any status codes that falls outside the range of 2xx cause this function to trigger
// Do something with response error
return Promise.reject(error);
});
//config参数,api里面封装;
//data需要传的参数
//bool是否加密传参
export default function request(config, data = {
}, bool = true) {
// access_token请求必须的
let date = new Date();
let operatorId = ""
let seq = "0001"
// let newData = crypto.Encrypt(JSON.stringify(data))//已备注封装部分
let newData = crypto.Encrypt(data)//因为前面已封装
let time = crypto.getTimeStamp(date)
let text = operatorId + newData + time + seq
let sign = crypto.HMACShaEncrypt(text) //HmacMD5( operatorId+data+timeStamp+seq)
let aesData = {
"data": newData,
"operatorId": operatorId,
"seq": seq,
"sign": sign,
"timeStamp": time //"20210122171030"
}
const Public = bool ?aesData : data;
let httpDefaultOpts = {
method: config.method || 'POST',
url: crypto.baseUrl + config.url,
headers: {
Authorization: config.needToken ? getToken('access_token') : 'Basic cGlnOnBpZw==',
'TENANT-ID': '1',
isToken: false,
},
data: Public
}
return new Promise((resolve, reject) => {
axios(httpDefaultOpts)
.then(res => {
//根据后端返回参数是否加密,对加密的进行解密
if(res.data.sign){
res = res.data.data && JSON.parse(crypto.Decrypt(res.data.data,))
if (resolveRes) {
resolve(res);
} else if (res.code === 0) {
resolve(res)
} else {
resolve(res.data)
crypto.message("err", res.data.msg)
}
}else{
console.log('不加密');
if (resolveRes) {
resolve(res);
} else if (res.data.code === 0) {
resolve(res.data)
} else {
resolve(res.data)
crypto.message("err", res.data.msg)
}
}
})
.catch(err => {
reject(err)
})
})
}
既然写都写到这了,接口调用也写一下吧
接口封装:
let needToken =true //调取接口参数时是否对token进行处理传参
//GET接口
// export const levelist = (level) => {
// return {
// method:'get',
// url: `/jd/dept/getByLevel/${level} `,
// needToken
// }
// }
//POST接口
export const childAreas ={
url:'/jd/areasCopy/list',
needToken
}
export const login = (data) => {
return {
url: `/jd/oauth/token?randomStr=${
data.randomStr}&code=${
data.code}&grant_type=password`,
}
}
接口使用
//人口文件引入axios文件放在原型链上,Vue.prototype.$axios= axios
//引入api.js 文件,按需使用接口
//调用:
import {
childAreas } from "@/api/api";
//第三个参数,是否对data进行加密处理;
this.$axios(childAreas , data,false).then(res =>{
})