软件测试 接口测试 接口鉴权 token鉴权 Mock Server 接口加解密 接口签名sign

1 接口鉴权

鉴定是否有访问接口的权限。

1.1 cookie鉴权

cookie是服务器产生的,保存在浏览器(客户端)中,http协议是无连接,无状态的。
cookie通过键值对的方式来保存记录。

cookie原理
第一次访问服务器的时候,服务器会产生cookie,通过响应头的set-cookie将cookie发送给浏览器,cookie保存在浏览器中。在浏览器第2-n次请求时都会带上cookie信息。
cookie包括信息:name,value,domain,path,expries,seize。
cookie有回话级cookie和持久化cookie。

1.2 session鉴权

session是服务器产生的,保存在服务器的内存中。session可以使用cookie来访问,通过sessionid。
session原理
当登录的时候,服务器会产生session,session通过cookie把sessionid传给客户端,然后在后面所有的请求里面都会自动带上sessionid,该sessionid和服务器内存中的sessionid对比,哦按段是都是同一个客户端。保存在服务器的内存中的session失效时间为30分钟。
例如:tomcat服务器,在apache-tomcat-9.0.60\conf目录下的web.xml文件中,session-timeout标签对session失效时间进行调整,如下图所示:
在这里插入图片描述

sessionid传值方式有隐藏域,url和cookie,绝大数情况下使用cookie传递。

1.3 token鉴权

token是服务器产生的,保存在服务器的硬盘中。接口测试通过一个专门获取token的接口或者登录接口获取token,获取token之后每次请求其他接口都必须带上token。

cookie,session,token的相同点和不同点?
相同点:都是在服务器产生的,都是用于鉴权。
不同点:保存的地方不同,cookie保存在浏览器中,session保存在服务器的内存中,token保存在服务器的硬盘中。
cookie保存不安全,保存非重要的数据。
session保存重要数据。
token是独立的鉴权,与session和cookie无关。

1.4 Postman的鉴权方式

bearer token鉴权就是发送一个鉴权码(令牌)。在请求页面中的Authorization,选择Bearer Token,填入token值,如下图所示:
在这里插入图片描述
basic Auth鉴权,通过用户名和密码实现鉴权,如下图所示:
在这里插入图片描述

2 Mock Server

mock测试就是测试过程中,对于一些不容易创建或者不容易获取的比较复杂的对象,用一个模拟的对象去代替。
mock是为了解决单元之间的耦合依赖关系。(桩服务)
比如:工作中前后端分离,前端已经开发好了,但是后端的接口没有开发好,此时使用Mock Server模拟一个接口提供给前端使用。

首先,新建Mock,填写URL地址{{url}}/testmock,响应信息为sucess,点击【Next】按钮,如下图所示:
在这里插入图片描述
为Mock server取testmock名,如下图所示:
在这里插入图片描述
新建完mock server,会有url地址,如下图所示:
在这里插入图片描述

新建完mock server,会自动生成testmock的环境,如下图所示:
在这里插入图片描述

新建完mock server,会自动生成testmock的集合,如下图所示:
在这里插入图片描述

新建完mock server,会自动生成testmock的请求,如下图所示:
在这里插入图片描述
在Body填充成功的提示词sucess,如下图所示:
在这里插入图片描述

打开浏览器,输入mock server给的url地址https://0cefbc69-52ee-440e-aec6-14e003fc4b32.mock.pstmn.io加上项目名testmock,会出现接口测试成功提示词,如下图所示:
在这里插入图片描述

3 接口加解密

接口加密。接口测试当中把传输的数据加密成密文再传输。
接口解密。获取密文后把密文还源成原始数据。

3.1 加密方式

对称式(私钥加密)有DES,AES,Base64
非对称加密(双钥加密)有RSA。公钥和私钥。
只加密不解密有DM5,SHA1,SHA3等等。主流使用DM5和SHA系列。

加密工具如下网址

https://www.bejson.com/

3.2 Postman实现加密接口

脚本生成url地址和加密脚本。
编写脚本api_login.py,运行结果如下:
在这里插入图片描述
一直开着api_login.py服务端,新建请求,输入url地址,在Pre-request Script调用Postman自带的MD5加密方法,加密账号和密码,并且将账号admin和密码123设置Wie全局变量,如下图所示:
在这里插入图片描述
设置参数,因为账号和密码的值设置为全局变量,所以可以直接调用这两个参数,如下图所示:
在这里插入图片描述

查看运行结果,成功,如下图所示:
在这里插入图片描述
查看MD5加密之后的账号和密码,如下图所示:
在这里插入图片描述

4 接口签名sign(难点)

接口签名是接口鉴权的一种,更加安全。

4.1 接口签名的定义

接口签名就是使用appid,appsecret,nonce(流水号),timestamp(时间戳),以及其他的各种参数按照一定的规则(一般是ASCII排序)组成用来识别你的账号有没有访问api接口的权限的字符串,组成之后再进行加密,这个经过加密的字符串就是sign签名。
流水号(nonce)是一串10位以上的随机一组数字或者随机的一组字符串。数字+字符串(guid)。
timestamp一般10分钟之内有效。

4.2 接口签名的作用

大大提高接口的安全性。
防止接口鉴权码泄露。
防止接口数据被篡改。签名针对的是所有的请求数据,只要有一个数字被改动了,那么sign就发生变化,请求就会失败。
防止接口被重复提交,nonce是唯一的,并且只有10分钟之内有效。

4.3 接口签名的规则

接口签名的规则很多,但是大同小异。
第一步,获取到所有的参数包括params和body,把所有的参数的key按照ASCII升序排列。例如:

{a:2,c:1,b:3}改为{a:2,b:3,c:1}

第二步,把参数按照key=value的方式组合,多个参数用&分开。例如:

a=2&b=3&c=1

第三步,用申请到的appid和appsecret拼接到参数的最前面。例如:

appid=123&appsecret=456&a=2&b=3&c=1

第四步,把订单号和时间戳拼接到参数的最后面。例如:

appid=123&appsecret=456&a=2&b=3&c=1&nonce=987654321&timestamp=089769123

第五步,把上述字符串通过MD5加密,加密之后大写,形成sign。例如:

sign=123QWEIOUSDAFKDJHFSKJDFHWER3498756

第六步,把sign放在url或者是请求体或者请求头中发送给服务器做鉴权,经常是放在请求头中

4.4 实战

在访问页面接口中获取csrf_token。在登录接口做接口签名。

4.4.1 访问页面接口

新建访问页面的接口,地址为http://47.107.116.139/phpwind/,点击【Send】按钮,响应页面,如下图所示:
在这里插入图片描述
找到csrf_token的值,在Tests中使用正则提取csrf_token的值,并且设置为全局变量,如下图所示:
在这里插入图片描述

4.4.2 登录接口(实现sign)

要在网站先注册账号,才有账号和密码使用。
(1)请求地址为http://47.107.116.139/phpwind/index.php?m=u&c=login&a=dorun
(2)在Body填入账号、密码、token以及必要的参数,如下图所示:
在这里插入图片描述
(3)在请求头Headers填入必要的参数,如下图所示:
在这里插入图片描述

(4)在Pre-request Script中进行接口签名
第一,定义appid和appsecret,如下所示:

var appid = "test"
var appsecret = "123"

第二,定义函数,获得任意长度的随机数字,获取nonce,如下所示:

//定义函数,获得任意长度的随机数字,为nonce使用
function getnonce(min,max){
    return Math.floor(Math.random() * (max - min +1)+min);
//获取nonce
var nonce = getnonce(1000000000,9999999999)
}

第三,获得时间戳,如下所示:

var timestamp = Date.now()

第四,获取Params中的参数,如下所示:

var params_args =  pm.request.url.query.members

第五,获取Body中的参数,使用JSON.stringify()将对象转换为字符串,如下所示:

var body_args = request.data;
console.log("body_args=" + JSON.stringify(body_args))

第六,将parmas和Body的参数组合,放在body_args中,如下所示:

for(var i=0;i<params_args.length;i++){
    body_args[params_args[i].key] = params_args[i].value;
}
console.log("params_body_args=" + JSON.stringify(body_args))

第七,把所有的参数的key按照ASCII码升序排序,需要定义按照key的ASCII码升序排序的函数,并调用该函数,如下所示:

//把所有的参数的key按照ASCII码升序排序
body_args = objectsort(body_args)
console.log("params_body_args=" + JSON.stringify(body_args))

//定义按照key的ASCII码升序排序的函数
function objectsort(obj){
    var new_key = Object.keys(obj).sort();
    console.log(new_key);
    var arr = {};
    for(var i =0;i<new_key.length;i++){
        arr[new_key[i]] = obj[new_key[i]];
    }
    return arr;
}

第八,把字典格式的参数组合成key=value&key=value,如下所示:

var new_string=""
for(var j in body_args){
    new_string += j + "=" + body_args[j] + "&"
}
console.log("new_string=" + JSON.stringify(new_string))

第九,在new_string的前面加上appid和appsecret,在new_string的后面加上nonce和timestamp,如下所示:

new_string ="appid=" + appid +"&" + "appsecret" + appsecret + "&" + new_string + "nonce=" + nonce + "&" +"timestamp=" + "&" + timestamp

第十,对new_string做MD5加密并大写,生成sign,sign保存为全局变量,如下所示:

var sign = CryptoJS.MD5("new_string").toString().toUpperCase();
console.log("sign="+sign)
pm.globals.set("sign", sign);

综上,在Pre-request Script代码如下:

//接口签名
//获取appid和appsecret
var appid = "test"
var appsecret = "123"
console.log("appid="+appid)
console.log("appsecret="+appsecret)
//获取nonce
var nonce = getnonce(1000000000,9999999999)
console.log("nonce=" + nonce)
//获得时间戳
var timestamp = Date.now()
console.log("timestamp=" + timestamp)

//获取params中的参数
var params_args =  pm.request.url.query.members
console.log("params_args="+params_args)

//获取Body中的参数,JSON.parse()将字符串转换为对象,JSON.stringify()对象转换为字符串
var body_args = request.data;
console.log("body_args=" + JSON.stringify(body_args))

//parmas和Body的参数组合
for(var i=0;i<params_args.length;i++){
    body_args[params_args[i].key] = params_args[i].value;
}
console.log("params_body_args=" + JSON.stringify(body_args))

//把所有的参数的key按照ASCII码升序排序
body_args = objectsort(body_args)
console.log("params_body_args=" + JSON.stringify(body_args))

//把字典格式的参数组合成key=value&key=value
var new_string=""
for(var j in body_args){
    new_string += j + "=" + body_args[j] + "&"
}
console.log("new_string=" + JSON.stringify(new_string))

//在new_string的前面加上appid和appsecret,在new_string的后面加上nonce,timestamp
new_string ="appid=" + appid +"&" + "appsecret=" + appsecret + "&" + new_string + "nonce=" + nonce + "&" +"timestamp=" + "&" + timestamp
console.log(new_string)

//对new_string做MD5加密并大写,生成sign,sign保存为全局变量
var sign = CryptoJS.MD5("new_string").toString().toUpperCase();
console.log("sign="+sign)
pm.globals.set("sign", sign);

//---------------------------------------------------
//定义函数,获得任意长度的随机数字,为nonce使用
function getnonce(min,max){
    return Math.floor(Math.random() * (max - min +1)+min);
}

//定义按照key的ASCII码升序排序的函数
function objectsort(obj){
    var new_key = Object.keys(obj).sort();
    console.log(new_key);
    var arr = {};
    for(var i =0;i<new_key.length;i++){
        arr[new_key[i]] = obj[new_key[i]];
    }
    return arr;
}

点击【Send】按钮,在console窗口查看结果,如下图所示:
在这里插入图片描述

最后将sign放在请求头中,发送给服务器做鉴权,如下图所示:
在这里插入图片描述

小结

接口鉴权分为cookie鉴权、session鉴权、token鉴权。
大多数情况下使用token鉴权

cookie,session,token的相同点和不同点?
相同点:都是在服务器产生的,都是用于鉴权。
不同点:保存的地方不同,cookie保存在浏览器中,session保存在服务器的内存中,token保存在服务器的硬盘中。
cookie保存不安全,保存非重要的数据。
session保存重要数据。
token是独立的鉴权,与session和cookie无关。

DM5和SHA系列是主流的加密方式。

==Mock Server==就是测试过程中,对于一些不容易创建或者不容易获取的比较复杂的对象,用一个模拟的对象去代替。
加密方式方式主要使用DM5加密和SHA系列。

接口签名sign规则(重点)
首先,定义appid,appsecret,nonce,timestamp。
然后,获取parmas和Body中的参数,并将两者组合成在一个字典中。
此外,根据字典的key的ASCII码升序排序,把字典格式转换为key=value&key=value形式,生成一个字符串。
在这个字符串前面加上appid和appsecret,后面加上nonce和timestamp。
对该字符串做MD5加密并大写,生成sign,sign保存为全局变量。
最后,把sign放在请求头中发送给服务器做鉴权。

  • 3
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值