为什么要token加密
此方案为2018年做小程序的时候实施
我们的小程序属于toB电商类,与金钱密切相关,因此对接口的安全性校验比较看重
处于产品性能+开发体验的考虑,我们没有将整体的接口数据都加密,而是每个接口的调用都会加上token,该token采用前后端加密匹配的方式来进行校验
前后端加密匹配
具体思路很简单,前后端获取到当前的时间戳time,加上当前用户的sk(小程序登录的session_key
),再加上一段前后端约定的文本密钥,进行加密,生成token
在全局接口请求的地方统一处理,将所有的请求url上,都挂上sk、time、token这三个参数,而约定的文本密钥不通过网络传输
后端拿到这三个参数之后,通过sk+time+前后端约定的文本密钥,加密生成token,与前端传入的token进行匹配,成功的话,返回正确的内容,校验错误的话就返回报错,接口返回请求错误
time校验
但如果这三个参数被人拿到了之后,直接恶意调用我们的接口怎么办?
解法:这里同时还有一个重要的校验,就是时间戳time的校验,这个time与后端的时间进行校验,差异阈值设置的比较小,超出这个差异值,也会提示报错
这个差异值在N秒之内,是多次实验的结果,在安全的同时也能保证正常的接口请求调用
具体前端代码展示
// 引用加密js
const jsSHA = require('../../libs/sha1')
// 在接口请求上,统一添加url参数
wx.pro.request = options => {
...
return new Promise((resolve, reject) => {
url: options.url + getToken() + '...',
...
}
// 获取token等参数
export function getToken() {
const time = new Date().getTime()
const sk = wx.getStorageSync('sk')
const shaObj = new jsSHA('SHA-1', 'TEXT')
shaObj.setHMACKey(sk, 'TEXT')
// 加上约定的字符串
shaObj.update('POST' + times + sk)
const token = shaObj.getHMAC('HEX')
return `?sk=${sk}&time=${time}&token=${token}`
}
为什么采用sha-1加密
除了sha系列的加密方法外,js常用的加密方法还有别的,md5、base64、以及RSA加密的jsencrypt.js
,这个网上资料很多
虽然sha1是可以暴力破解的,不过在正常破解资源的情况下,还是足够安全,加上加密效率也ok,在互联网中的使用也算比较普遍
可以查阅 jsSHA github来把玩一下sha的各种加密方法,现在来看,sha-1有点落伍了,sha-3还未普及,使用的最多的是sha-2
后记
如上的接口校验工作,后来在项目中运行的比较平稳,没有出过相关的安全问题
不过这只是前端安全里面的冰山一角,尤其是电商类项目,还有很多安全相关的事情需要做