1.输入验证
对传递的数据的格式、长度、类型(前端和后端都要)进行校验。
对黑白名单校验:比如前端传递了一个用户名,可以搜索该用户是否在白名单或者黑名单列表。
针对黑名单校验,比如:
// 手机号验证码登录的时候,需要check一下手机号
async sendAuthCode(phone){
if(!_.isString(v))return false
const phone = phone.replace(/[a-zA-Z]/gi,'')
if(phone.length!==11) return false
const forbidden = ['170','171','165','167']
const isR = forbidden.some(item=>phone.startsWith(item))
if(isR)return false
}
2.身份认证与授权
身份认证(属于node后端责任),核心思想:后端A向第三方服务B端发起请求的时候在请求头添加一个3个字段:
projectKey,appKey,authorization,
其中前两个key是A和B商量好的一串码(比如dfs3290sdf)
authorization是通过给param参数转成md5,混合一堆content-type,uri之类的配合B提供的密钥secretKey进行hmac编码,生成签名signature。
然后B端根据相反的规则解析这三个字段,与自己手上的projectKey,appKey,secretKey进行对比
上代码:
// 伪代码
const Authorization = this.getAuthorization('POST', reqParams, this.contentType, this.uri, date, this.secretKey, this.accessKey);
const headers = {
'Content-Type': this.contentType,
'Authorization': Authorization,
'projectKey': this.projectKey,
'appKey': this.appKey,
'Date': date,
'X-Forwarded-For': '192.168.42.94'
}
const options = {
method: 'POST',
headers
};
const res = await this.Fetch(url, options, param);
getAuthorization(method, params, contentType, uri, date, secretKey, accessKey): string {
const md5 = this.getContentMD5(params);
const constToSign = method + '\n' + md5 + '\n' + contentType + '\n' + date + '\n' + uri;
// 将constToSign施行utf-8转换
const utf8Data = Buffer.from(constToSign, 'utf8');
// 使用HMAC-SHA1和密钥进行编码
const hmac = crypto.createHmac('sha1', secretKey);
hmac.update(utf8Data);
const encodedData = hmac.digest();
// 使用Base64进行最后的编码
const signature = encodedData.toString('base64');
return `${accessKey}:${signature}`;
}
getContentMD5(params) {
let contentMD5 = '';
const jsonString = qs.stringify(params);
contentMD5 = crypto.createHash('md5').update(jsonString).digest('base64')
return contentMD5;
}