training content
Training Project: very green - found written test module interface, a single interface to process the script;
Tools: postman
Training methods
1) postman instructions
2) Project interface documentation and registration step principle
One, first understand the postman use
Two, OpenSDK Login principle (APP login), all post request method
APP Login
The first step: Get oauth20_state
The required parameters: response_type: code
client_id:Q_GPxHQAQZ-kYq3o1hoXtg
state:login
redirect_uri:
http://www.utouu.com/
"Oauth20_state": "98315c0d-85e5-4d4b-af5f-5f4eccaea21e" with an expiry time, every 10 minutes reacquisition
Step Two: Get the code
The required parameters: authCode: 10005,100020,100022,100021
Step to get on: oauth20_state
username: account number 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