培训内容
实训项目:非常果岭—发现模块接口测试,单接口、流程脚本编写;
使用工具:postman
培训方式
1)postman使用说明
2)项目接口文档和登录步骤原理
 
一、首先了解postman使用
 
二、OpenSDK登录原理(APP登录),请求方式都是post
APP登录
第一步:获取oauth20_state
所需参数:response_type:code
                client_id:Q_GPxHQAQZ-kYq3o1hoXtg
            state:login
            redirect_uri:http://www.utouu.com/
"oauth20_state": "98315c0d-85e5-4d4b-af5f-5f4eccaea21e"有失效时间,每隔10分钟重新获取
第二步:获取code
所需参数:authCode:10005,100020,100022,100021
          oauth20_state:上一步获得
          username:帐号13699999998
          password:密码a111111
"code": "6d83408a-aaf8-4dc3-9c5f-d5baa76a6e1a",
第三步:获取access_token
所需参数:grant_type:authorization_code
          client_id:Q_GPxHQAQZ-kYq3o1hoXtg
          client_secret:DCXqFTbkQU2EA47yqSa3VA
          code:上一步获得
          redirect_uri:http://www.utouu.com/
"access_token": "39e6c176-bdb9-48f0-b023-fccf2734ed6a"
第四步:获取openid和appid
"openid": "UVoUy6IyhKvuLtDPvP_qAnouExXs",
"client_id": "Q_GPxHQAQZ-kYq3o1hoXtg",
所需参数:access_token:上一步获得
第五步登录:以非常果岭为例登录接口,获取userid
app.utgreen.test.utsoft.cn/oauth-authorize/login?openId=UVoUy6IyhKvuLtDPvP_qAnouExXs&accessToken=d4771e6f-c862-499d-ae50-d044b84ca654&udid=11&appid=Q_GPxHQAQZ-kYq3o1hoXtg
"userId": "b5a5aba1-30aa-45df-b474-b84731860047",
---------------------------------------------------------------------------------------------------------------------------
test中的打印语句:
tests["Body matches string"] =responseBody.has("string_you_want_to_search");
tests[timestamp] = timestamp;
帐号密码:
18140048905,a111111
18140048906,a111111
18140048907,a111111
18140048908,a111111
18140048909,a111111
18140048900,a111111
 
设置一个环境变量由一个时间函数返回他的值
postman.setEnvironmentVariable('timestampHeader',new Date());
 
 
遗留
2.APP接口的访问
采用OpenSDK登录的APP接口,大部分除了接口文档需要的参数外,还需要如下参数:
utouu-open-client-ticket:用户登录的ticket
utouu-open-client-appid:在登录过程中已经获取到
utouu-open-client-sign:获取的sign
utouu-open-client-time:登录的时间戳
sign校验原理
1.获取得到时间戳
var timestamp = (new Date()).valueOf();
postman.setEnvironmentVariable('time',timestamp);
2.取得传入参数并对key升序排序,对value进行字符串拼接
postman:如何将A请求中responseBody中的参数值传入到下一个请求B的request中作为参数发送请求 

https://my.oschina.net/1157600353/blog/814237
3.对时间戳采用MD5加密,加密长度16位

  1 // 对时间戳加密
2 // 方法一:MD5函数加密
3 String.prototype.MD5 = function (bit)
4 {
5 var sMessage = this;
6 function RotateLeft(lValue, iShiftBits) { return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits)); }
7 function AddUnsigned(lX,lY)
8 {
9 var lX4,lY4,lX8,lY8,lResult;
10 lX8 = (lX & 0x80000000);
11 lY8 = (lY & 0x80000000);
12 lX4 = (lX & 0x40000000);
13 lY4 = (lY & 0x40000000);
14 lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
15 if (lX4 & lY4) return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
16 if (lX4 | lY4)
17 {
18 if (lResult & 0x40000000) return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
19 else return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
20 } else return (lResult ^ lX8 ^ lY8);
21 }
22 function F(x,y,z) { return (x & y) | ((~x) & z); }
23 function G(x,y,z) { return (x & z) | (y & (~z)); }
24 function H(x,y,z) { return (x ^ y ^ z); }
25 function I(x,y,z) { return (y ^ (x | (~z))); }
26 function FF(a,b,c,d,x,s,ac)
27 {
28 a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
29 return AddUnsigned(RotateLeft(a, s), b);
30 }
31 function GG(a,b,c,d,x,s,ac)
32 {
33 a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
34 return AddUnsigned(RotateLeft(a, s), b);
35 }
36 function HH(a,b,c,d,x,s,ac)
37 {
38 a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
39 return AddUnsigned(RotateLeft(a, s), b);
40 }
41 function II(a,b,c,d,x,s,ac)
42 {
43 a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
44 return AddUnsigned(RotateLeft(a, s), b);
45 }
46 function ConvertToWordArray(sMessage)
47 {
48 var lWordCount;
49 var lMessageLength = sMessage.length;
50 var lNumberOfWords_temp1=lMessageLength + 8;
51 var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
52 var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
53 var lWordArray=Array(lNumberOfWords-1);
54 var lBytePosition = 0;
55 var lByteCount = 0;
56 while ( lByteCount < lMessageLength )
57 {
58 lWordCount = (lByteCount-(lByteCount % 4))/4;
59 lBytePosition = (lByteCount % 4)*8;
60 lWordArray[lWordCount] = (lWordArray[lWordCount] | (sMessage.charCodeAt(lByteCount)<<lBytePosition));
61 lByteCount++;
62 }
63 lWordCount = (lByteCount-(lByteCount % 4))/4;
64 lBytePosition = (lByteCount % 4)*8;
65 lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
66 lWordArray[lNumberOfWords-2] = lMessageLength<<3;
67 lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
68 return lWordArray;
69 }
70 function WordToHex(lValue)
71 {
72 var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
73 for (lCount = 0;lCount<=3;lCount++)
74 {
75 lByte = (lValue>>>(lCount*8)) & 255;
76 WordToHexValue_temp = "0" + lByte.toString(16);
77 WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
78 }
79 return WordToHexValue;
80 }
81 var x=Array();
82 var k,AA,BB,CC,DD,a,b,c,d
83 var S11=7, S12=12, S13=17, S14=22;
84 var S21=5, S22=9 , S23=14, S24=20;
85 var S31=4, S32=11, S33=16, S34=23;
86 var S41=6, S42=10, S43=15, S44=21;
87 // Steps 1 and 2. Append padding bits and length and convert to words
88 x = ConvertToWordArray(sMessage);
89 // Step 3. Initialise
90 a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
91 // Step 4. Process the message in 16-word blocks
92 for (k=0;k<x.length;k+=16)
93 {
94 AA=a; BB=b; CC=c; DD=d;
95 a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
96 d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
97 c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
98 b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
99 a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
100 d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
101 c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
102 b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
103 a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
104 d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
105 c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
106 b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
107 a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
108 d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
109 c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
110 b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
111 a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
112 d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
113 c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
114 b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
115 a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
116 d=GG(d,a,b,c,x[k+10],S22,0x2441453);
117 c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
118 b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
119 a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
120 d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
121 c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
122 b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
123 a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
124 d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
125 c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
126 b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
127 a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
128 d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
129 c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
130 b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
131 a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
132 d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
133 c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
134 b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
135 a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
136 d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
137 c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
138 b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
139 a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
140 d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
141 c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
142 b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
143 a=II(a,b,c,d,x[k+0], S41,0xF4292244);
144 d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
145 c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
146 b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
147 a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
148 d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
149 c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
150 b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
151 a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
152 d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
153 c=II(c,d,a,b,x[k+6], S43,0xA3014314);
154 b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
155 a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
156 d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
157 c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
158 b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
159 a=AddUnsigned(a,AA); b=AddUnsigned(b,BB); c=AddUnsigned(c,CC); d=AddUnsigned(d,DD);
160 }
161 if(bit==32)
162 {
163 return WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);
164 }
165 else
166 {
167 return WordToHex(b)+WordToHex(c);
168 }
169 }
170 // 将时间戳转换为字符串格式
171 var str1 = timestamp.toString(); // 转换格式
172 var md16 = str1.MD5(); // 调用加密方法,默认为16位加密
173 postman.setEnvironmentVariable('timestampMD5',md16);
174
175 // 方法二:使用CryptoJS库所带的MD5加密
176 var str2 = timestamp.toString();// 转换格式
177 var md161 = CryptoJS.MD5(str2).toString(); // 加密后转换格式
178 var md162 = md161.substr(8,16); // 获取中间16位MD5码
179 postman.setEnvironmentVariable('2',md162);
4.将value与加密后的时间戳拼接,注意:拼接时加冒号分隔
var long = "e99b4dbd-60a8-4738-b2a0-9e0f97c1e9e9" + ":" + md16;
postman.setEnvironmentVariable('valueAndMD5',long);
 
对拼接后的值进行Base64加密

// 方法一:使用函数对拼接后的字符进行Base64加密
function Base64() {
// private property
_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
// public method for encoding
this.encode = function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = _utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
_keyStr.charAt(enc3) + _keyStr.charAt(enc4);
}
return output;
}
// public method for decoding
this.decode = function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = _utf8_decode(output);
return output;
}
// private method for UTF-8 encoding
_utf8_encode = function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
// private method for UTF-8 decoding
_utf8_decode = function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
var b64 = new Base64(); // 创建一个对象
var sign = b64.encode(long); // 调用函数中的encode方法进行64位编码获取到对应的sign
postman.setEnvironmentVariable('signBase64',sign); // 方法二:使用CryptoJS库对字符串进行Base64转码,加密就是转码
// 拼接后的long是utf-8格式的字符串
var words = CryptoJS.enc.Utf8.parse(long); // 转换成WordArray object
postman.setEnvironmentVariable('1',words);
var sign1 = CryptoJS.enc.Base64.stringify(words); // 将数组对象进行转为Base64格式字符串
postman.setEnvironmentVariable('2',sign1);
 
5.得到sign

postman项目接口文档和登录步骤原理的更多相关文章

  1. [Django REST framework - 自动生成接口文档、分页]

    [Django REST framework - 自动生成接口文档.分页] 自动生成接口文档 # 后端人员写好接口,编写接口文档,给前端人员看,前端人员依照接口文档开发 # 公司里主流 -后端,使用w ...

  2. 推荐一款接口文档在线管理系统-MinDoc

    项目简介 MinDoc 是一款针对IT团队开发的简单好用的文档管理系统. MinDoc 的前身是 SmartWiki 文档系统.SmartWiki 是基于 PHP 框架 laravel 开发的一款文档 ...

  3. Spring Boot 系列(七)Swagger2-生成RESTful接口文档

    Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.总体目标是使客户端和文件系统作为服务器以同样的速度来更新.文件的方法,参数和模型紧密集成到服 ...

  4. 《MinDoc 接口文档在线管理系统》

    项目简介 MinDoc 是一款针对IT团队开发的简单好用的文档管理系统. MinDoc 的前身是 SmartWiki 文档系统.SmartWiki 是基于 PHP 框架 laravel 开发的一款文档 ...

  5. SpringBoot开发mockserver及生成swagger接口文档

    通过springboot开发mock server,包含get及post接口,用于练习接口自动化及jmeter很方便 当然,也为后面jenkins持续集成做基础(开发push代码后  → jenkin ...

  6. 如何使用Swagger-UI在线生成漂亮的接口文档

    一.简单介绍 Swagger是一个实现了OpenAPI(OpenAPI Specification)规范的工具集.OpenAPI是Linux基金会的一个项目,试图通过定义一种用来描述API格式或API ...

  7. spring-boot-route(五)整合Swagger生成接口文档

    目前,大多数公司都采用了前后端分离的开发模式,为了解决前后端人员的沟通问题,后端人员在开发接口的时候会选择使用swagger2来生成对应的接口文档,swagger2提供了强大的页面调试功能,这样可以有 ...

  8. 接口文档管理工具-Postman、Swagger、RAP(转载)

    接口文档管理工具-Postman.Swagger.RAP 转自:http://www.51testing.com/html/10/n-3715910.html 在项目开发测试中,接口文档是贯穿始终的. ...

  9. springboot项目利用Swagger2生成在线接口文档

    Swagger简介. Swagger2是一款restful接口文档在线生成和在线调试工具.很多项目团队利用Swagger自动生成接口文档,保证接口文档和代码同步更新.在线调试.简单地说,你可以利用这个 ...

随机推荐

  1. DRF框架在嵌套关系下实现嵌套对象字段的过滤

    当需要对关联对象的字段进行选择性显示时,在所对应的serializer类中声明引用的字段. 例如: class TrackSerializer(serializers.ModelSerializer) ...

  2. 解压安装Cacti在apache中的补充

    如果你不是安装 Cacti 到 Apache 默认的网络目录文件夹位置,那么在 /etc/httpd/conf.d 中新增配置文件 cacti.conf,并且按如下内容编辑.设置 /your/cact ...

  3. Hive分析统计离线日志信息

    关注公众号:分享电脑学习回复"百度云盘" 可以免费获取所有学习文档的代码(不定期更新)云盘目录说明:tools目录是安装包res 目录是每一个课件对应的代码和资源等doc 目录是一 ...

  4. Java 简单操作hdfs API

    注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6632047118376780295/ 启动Hadoop出现问题:datanode的clusterID 和 name ...

  5. Amazon EKS 中 EFS 持久性存储

    作者:SRE运维博客 博客地址:https://www.cnsre.cn/ 文章地址:https://www.cnsre.cn/posts/220110850573/ 相关话题:https://www ...

  6. EF中使用事务

    using (var db = new dbEntities()) { //第一个坑,需要手动open db.Database.Connection.Open(); using (var tran = ...

  7. 【解决了一个小问题】gin框架中出现如下错误:"[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 500"

    POST到数据到一条gin框架的接口后,客户端收到400错误,并且返回了业务中返回的"decode json fail". 关键代码是: func report(c *gin.Co ...

  8. RT-Thread移植到stm32

    一.移植RT-Thread准备 RT-Thread源码 源码版本和下载方式,可以参考RT-Thread移植入门学习. keil软件 STM32工程项目模板 因为每一厂家提供的库文件可能有一些区别,在移 ...

  9. 通过location.search来获取页面传来的参数

    获取页面传来的参数 <div> <script> function GetQueryString(name) { var reg = new RegExp("(^|& ...

  10. 【Azure Developer】使用 Azure Python SDK时,遇见 The resource principal named https://management.azure.com was not found in the tenant China Azure问题的解决办法

    问题描述 在使用Python SDK时候,登录到China Azure (Mooncake)并访问AlertsManagement资源时候,时常遇见  EnvironmentCredential: A ...