温故知新,.Net Core遇见Postman(API Development),进阶分布式微服务高效调式
什么是Postman

环境变量(Environments)
全局协议
| 描述 | 变量 | 初始值 | 当前值 |
|---|---|---|---|
| 请求协议 | request_protocol |
http |
http |
授权信息
| 描述 | 变量 | 初始值 | 当前值 |
|---|---|---|---|
| 授权-子系统Token | auth_token_subsystem |
||
| 授权-用户Token | auth_token_user |
||
| 授权-管理员Token | auth_token_user_admin |
||
| 授权-客户端Token | auth_token_client |
网关信息
| 描述 | 变量 | 初始值 | 当前值 |
|---|---|---|---|
| 网关域名 | gateway_hostname |
gateway.xxxxx.com |
gateway.xxxxx.com |
| 请求地址 | request_hostname |
gateway.xxxxx.com |
gateway.xxxxx.com |
对外授权
| 描述 | 变量 | 初始值 | 当前值 |
|---|---|---|---|
| 授权-应用Id | auth_app_id |
||
| 授权-应用密钥 | auth_app_secret |
||
| 授权-签名方式 | auth_sign_type |
内部授权
| 描述 | 变量 | 初始值 | 当前值 |
|---|---|---|---|
| 子系统授权-服务密钥 | auth_sub_system_secret |
||
| 子系统授权-服务标识 | auth_sub_system_service_id |
||
| 终端请求标识 | auth_request_flag |
请求路径
| 描述 | 变量 | 初始值 | 当前值 |
|---|---|---|---|
| 子系统授权-请求路径 | auth_sub_system_token_path |
||
| 对外签名-请求路径 | auth_app_create_sign_path |
||
| Web后台-登录请求路径 | auth_token_user_path |
账号信息
| 描述 | 变量 | 初始值 | 当前值 |
|---|---|---|---|
| Web后台-登录用户名 | web_portal_user_name |
||
| Web后台-登录用户密码 | web_portal_user_pwd |
||
| Web后台-登录终端域名 | web_portal_hostname |
||
| Web后台-用户密码摘要 | web_portal_user_pwd_hash |
||
| Web后台-管理用户名 | web_portal_admin_name |
||
| Web后台-管理用户密码 | web_portal_admin_pwd |
||
| Web后台-管理终端域名 | web_portal_admin_hostname |
||
| Web后台-用户密码摘要 | web_portal_admin_pwd_hash |
请求前置脚本(Pre-request Script)
Base64加解密字符串
CryptoJS
// 待加密字符串
var byEncryptStr = "";
// 加密Base64
var base64Encrypt = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(byEncryptStr));
console.log('base64Encrypt:', base64Encrypt);
// 解密Base64
var base64Decrypt = CryptoJS.enc.Base64.parse(base64Encrypt).toString(CryptoJS.enc.Utf8);
console.log('base64Decrypt:', base64Decrypt);
MD5摘要字符串
CryptoJS
// 待加密字符串
var byEncryptStr = "";
var hash = CryptoJS.MD5(byEncryptStr).toString();
移除请求内容体的Json注释
// 移除Json注释
const rawData = pm.request.body.toString();
const strippedData = rawData.replace(/\\"|"(?:\\"|[^"])*"|(\/\/.*|\/\*[\s\S]*?\*\/)/g, (m, g) => g ? "" : m)
pm.request.body.update(strippedData);
// 获取当前环境请求体
var requestJson = JSON.parse(pm.request.body.raw);
获取并赋值子系统Token
// 获取当前环境请求协议
var request_protocol = pm.environment.get("request_protocol");
console.log("获取当前环境请求协议:" + request_protocol);
// 获取当前环境网关域名
var gateway_hostname = pm.environment.get("gateway_hostname");
console.log("获取当前环境网关域名:" + gateway_hostname);
// 获取当前环境用户服务
var gateway_service_user = pm.environment.get("gateway_service_user");
console.log("获取当前环境用户服务:" + gateway_service_user);
// 获取当前环境子系统授权路径
var auth_sub_system_token_path = pm.environment.get("auth_sub_system_token_path");
console.log("获取当前环境子系统授权路径:" + auth_sub_system_token_path);
// 拼接并获取子系统授权的请求地址
var getSubSystemTokenUrl = request_protocol + '://' + gateway_hostname + "/" + gateway_service_user + '/' + auth_sub_system_token_path;
console.log("拼接并获取子系统授权的请求地址:" + getSubSystemTokenUrl);
// 获取当前环境子系统密钥
var auth_sub_system_secret = pm.environment.get("auth_sub_system_secret");
console.log("获取当前环境子系统密钥:" + auth_sub_system_secret);
// 获取当前环境子系统身份标识
var auth_sub_system_service_id = pm.environment.get("auth_sub_system_service_id");
console.log("获取当前环境子系统身份标识:" + auth_sub_system_service_id);
// 定义Post请求方法及参数
const echoPostRequest = {
url: getSubSystemTokenUrl,
method: 'POST',
header: [
"Content-Type: application/json",
"Accept: application/json"
],
body: {
mode: 'raw',
raw: JSON.stringify({
"secret": auth_sub_system_secret,
"sid": auth_sub_system_service_id
})
}
};
// 发送自定义请求
pm.sendRequest(echoPostRequest, function (err, response) {
// 将返回结果中的Data赋值到环境变量
pm.environment.set("auth_token_subsystem", response.json().data);
});
获取并赋值对外接口签名
// 获取当前环境请求协议
var request_protocol = pm.environment.get("request_protocol");
console.log("获取当前环境请求协议:" + request_protocol);
// 获取当前环境网关地址
var gateway_path = pm.environment.get("gateway_path");
console.log("获取当前环境网关地址:" + gateway_path);
// 获取当前环境对外服务
var gateway_service_public = pm.environment.get("gateway_service_public");
console.log("获取当前环境对外服务:" + gateway_service_public);
// 获取当前环境生成签名的路径
var auth_app_create_sign_path = pm.environment.get("auth_app_create_sign_path");
console.log("获取当前环境生成签名的路径:" + auth_app_create_sign_path);
// 拼接并获取对外授权签名的请求地址
var createSignUrl = "";
// 判断纯数字的正则表达式
var reg = /^[0-9]+.?[0-9]*$/;
// 如果网关服务名称是纯数字,即服务端口号,说明不走网关模式,即调式模式
if(reg.test(gateway_service_public))
{
createSignUrl = request_protocol + '://' + gateway_path + ":" + gateway_service_public + '/' + auth_app_create_sign_path;
}
else
{
createSignUrl = request_protocol + '://' + gateway_path + "/" + gateway_service_public + '/' + auth_app_create_sign_path;
}
console.log("拼接并获取对外授权签名的请求地址:" + createSignUrl);
// 获取当前环境应用密钥
var auth_app_secret = pm.environment.get("auth_app_secret");
console.log("获取当前环境应用密钥:" + auth_app_secret);
// 定义Post请求方法及参数
const echoPostRequest = {
url: createSignUrl,
method: 'POST',
header: [
"Content-Type: multipart/form-data",
"Accept: application/json"
],
body: {
mode: 'formdata',
formdata: [
{
key: "SignKey", value: auth_app_secret, disabled: false, description: { content:"", type:"text/plain" }
},
{
key: "Content", value: pm.request.body.raw, disabled: false, description: { content:"", type:"text/plain" }
}
]
}
};
// 发送自定义请求
pm.sendRequest(echoPostRequest, function (err, response) {
// 将返回结果中的Sign赋值到环境变量
pm.environment.set("request_sign", response.json().data.sign);
});
登陆并获取Web后台授权Token
// 获取当前环境请求协议
var request_protocol = pm.environment.get("request_protocol");
console.log("获取当前环境请求协议:" + request_protocol);
// 获取当前环境网关域名
var gateway_hostname = pm.environment.get("gateway_hostname");
console.log("获取当前环境网关域名:" + gateway_hostname);
// 获取当前环境用户服务
var gateway_service_user = pm.environment.get("gateway_service_user");
console.log("获取当前环境用户服务:" + gateway_service_user);
// 获取当前环境Web后台登陆路径
var auth_token_user_path = pm.environment.get("auth_token_user_path");
console.log("获取当前环境Web后台登陆路径:" + auth_token_user_path);
// 拼接并获取Web后台登陆的请求地址
var getWebPortalTokenUrl = request_protocol + '://' + gateway_hostname + "/" + gateway_service_user + '/' + auth_token_user_path;
console.log("拼接并获取Web后台登陆的请求地址:" + getWebPortalTokenUrl);
// 获取当前环境Web后台登陆的域名
var web_portal_hostname = pm.environment.get("web_portal_hostname");
console.log("获取当前环境Web后台登陆的域名:" + web_portal_hostname);
// 获取当前环境Web后台登陆的用户名
var web_portal_user_name = pm.environment.get("web_portal_user_name");
console.log("获取当前环境Web后台登陆的用户名:" + web_portal_user_name);
// 获取当前环境Web后台登陆的密码
var web_portal_user_pwd = pm.environment.get("web_portal_user_pwd");
console.log("获取当前环境Web后台登陆的密码:" + web_portal_user_pwd);
// 获取当前环境Web后台登陆的密码摘要
var web_portal_user_pwd_hash = CryptoJS.MD5(web_portal_user_pwd).toString();
console.log("获取当前环境Web后台登陆的密码摘要:" + web_portal_user_pwd_hash);
// 定义Post请求方法及参数
const echoPostRequest = {
url: getWebPortalTokenUrl,
method: 'POST',
header: [
"Content-Type: application/json",
"Accept: application/json"
],
body: {
mode: 'raw',
raw: JSON.stringify({
"username": web_portal_user_name,
"password": web_portal_user_pwd_hash,
"domain": web_portal_hostname
})
}
};
// 发送自定义请求
pm.sendRequest(echoPostRequest, function (err, response) {
// 将返回结果中的Data赋值到环境变量
pm.environment.set("auth_token_user", response.json().data.token);
});
登陆并获取管理后台授权Token
// 获取当前环境请求协议
var request_protocol = pm.environment.get("request_protocol");
console.log("获取当前环境请求协议:" + request_protocol);
// 获取当前环境网关域名
var gateway_hostname = pm.environment.get("gateway_hostname");
console.log("获取当前环境网关域名:" + gateway_hostname);
// 获取当前环境用户服务
var gateway_service_user = pm.environment.get("gateway_service_user");
console.log("获取当前环境用户服务:" + gateway_service_user);
// 获取当前环境Web后台登陆路径
var auth_token_user_path = pm.environment.get("auth_token_user_path");
console.log("获取当前环境Web后台登陆路径:" + auth_token_user_path);
// 拼接并获取Web后台登陆的请求地址
var getWebPortalTokenUrl = request_protocol + '://' + gateway_hostname + "/" + gateway_service_user + '/' + auth_token_user_path;
console.log("拼接并获取Web后台登陆的请求地址:" + getWebPortalTokenUrl);
// 获取当前环境Web后台登陆的域名
var web_portal_admin_hostname = pm.environment.get("web_portal_admin_hostname");
console.log("获取当前环境Web后台登陆的域名:" + web_portal_admin_hostname);
// 获取当前环境Web后台登陆的用户名
var web_portal_admin_name = pm.environment.get("web_portal_admin_name");
console.log("获取当前环境Web后台登陆的用户名:" + web_portal_admin_name);
// 获取当前环境Web后台登陆的密码
var web_portal_admin_pwd = pm.environment.get("web_portal_admin_pwd");
console.log("获取当前环境Web后台登陆的密码:" + web_portal_admin_pwd);
// 获取当前环境Web后台登陆的密码摘要
var web_portal_admin_pwd_hash = CryptoJS.MD5(web_portal_admin_pwd).toString();
console.log("获取当前环境Web后台登陆的密码摘要:" + web_portal_admin_pwd_hash);
// 定义Post请求方法及参数
const echoPostRequest = {
url: getWebPortalTokenUrl,
method: 'POST',
header: [
"Content-Type: application/json",
"Accept: application/json"
],
body: {
mode: 'raw',
raw: JSON.stringify({
"username": web_portal_admin_name,
"password": web_portal_admin_pwd_hash,
"domain": web_portal_admin_hostname
})
}
};
// 发送自定义请求
pm.sendRequest(echoPostRequest, function (err, response) {
// 将返回结果中的Data赋值到环境变量
pm.environment.set("auth_token_user_admin", response.json().data.token);
});
请求后置脚本(Tests)
响应结果可视化(Visualize)
var template = `
<table bgcolor="#FFFFFF">
<tr>
<th>商户ID</th>
<th>商户名称</th>
<th>开始时间</th>
<th>结束时间</th>
<th>耗时(秒)</th>
</tr>
{{#each response}}
<tr>
<td>{{tenantId}}</td>
<td>{{tenantName}}</td>
<td>{{startTime}}</td>
<td>{{endTime}}</td>
<td>{{costTime}}</td>
</tr>
{{/each}}
</table>
`;
// Set visualizer
pm.visualizer.set(template, {
// Pass the response body parsed as JSON as `data`
response: pm.response.json().data.details.dataSource
});

参考
- Postman(接口自动化测试)
- postman pre-request script (random array)
- postman pre-request script (random value)
- postman pre-request script (post raw2)
- postman pre-request script (get)
- postman pre-request script (post raw)
- postman pre-request script (post form-data)
- postman tests (find value in response)
- Visualizing responses
- Postman进行简单的base64编码解码请求测试
- 接口测试 postman 如何将 response base64 解码呢
- Change request body in pre-request script
- Feature request: Raw body editor JSON comment
温故知新,.Net Core遇见Postman(API Development),进阶分布式微服务高效调式的更多相关文章
- .Net Core 分布式微服务框架 - Jimu 添加 Swagger 支持
系列文章 .Net Core 分布式微服务框架介绍 - Jimu .Net Core 分布式微服务框架 - Jimu 添加 Swagger 支持 一.前言 最近有空就优化 Jimu (一个基于.Net ...
- .Net Core 分布式微服务框架介绍 - Jimu
系列文章 .Net Core 分布式微服务框架介绍 - Jimu .Net Core 分布式微服务框架 - Jimu 添加 Swagger 支持 一.前言 近些年一直浸淫在 .Net 平台做企业应用开 ...
- Net Core 分布式微服务框架
Jimu : .Net Core 分布式微服务框架介绍 https://www.cnblogs.com/grissom007/p/9291345.html 一.前言 近些年一直浸淫在 .Net 平台做 ...
- 温故知新,使用ASP.NET Core创建Web API,永远第一次
ASP.NET Core简介 ASP.NET Core是一个跨平台的高性能开源框架,用于生成启用云且连接Internet的新式应用. 使用ASP.NET Core,您可以: 生成Web应用和服务.物联 ...
- 温故知新,Blazor遇见大写人民币翻译机(ChineseYuanParser),践行WebAssembly SPA的实践之路
背景 在之前<温故知新,.Net Core遇见Blazor(FluentUI),属于未来的SPA框架>中我们已经初步了解了Blazor的相关概念,并且根据官方的指引完成了<创建我的第 ...
- 使用ASP.NET Core构建RESTful API的技术指南
译者荐语:利用周末的时间,本人拜读了长沙.NET技术社区翻译的技术标准<微软RESTFul API指南>,打算按照步骤写一个完整的教程,后来无意中看到了这篇文章,与我要写的主题有不少相似之 ...
- .Net Core中的Api版本控制
原文链接:API Versioning in .Net Core 作者:Neel Bhatt 简介 Api的版本控制是Api开发中经常遇到的问题, 在大部分中大型项目都需要使用到Api的版本控制 在本 ...
- 【转】.Net Core中的Api版本控制
原文链接:API Versioning in .Net Core 作者:Neel Bhatt 简介 Api的版本控制是Api开发中经常遇到的问题, 在大部分中大型项目都需要使用到Api的版本控制 在本 ...
- 技术的正宗与野路子 c#, AOP动态代理实现动态权限控制(一) 探索基于.NET下实现一句话木马之asmx篇 asp.net core 系列 9 环境(Development、Staging 、Production)
黄衫女子的武功似乎与周芷若乃是一路,飘忽灵动,变幻无方,但举手抬足之间却是正而不邪,如说周芷若形似鬼魅,那黄衫女子便是态拟神仙. 这段描写出自<倚天屠龙记>第三十八回. “九阴神抓”本是& ...
随机推荐
- mysql 索引十连问| 剑指 offer - mysql
以下是结合网上及此前面试时遇到的一些关于mysql索引的面试题. 若对mysql索引不太了解可先翻阅相关文章 大白话 mysql 之深入浅出索引原理 - 上 大白话 mysql 之深入浅出索引原理 - ...
- python将控制台输出保存到文件
python将控制台输出保存到文件 在平时工作中,有时我们需要将控制台输出保存到文件 1.命令行用>覆盖写入和>>追加写入 for i in range(10000): prin ...
- dmesg -w 查看硬件参数
dmesg -w 查看硬件参数 14,笔记本硬件问题,使用dmesg -w可以看到,内核不断受到硬件过来的热插拔信号
- Ansible_处理失败的任务
一.Ansible处理任务失败 1.管理play中任务错误 1️⃣:Ansible评估任务的返回代码,从而确定任务是成功还是失败 2️⃣:通常而言,当任务失败时,Ansible将立即在该主机上中止pl ...
- nginx location标签的匹配规则
location的匹配 匹配符 匹配规则 优先级 = 精确匹配 1 ^~ 以某个字符串开头 2 ~ 区分大小写的正则匹配 3 ~* 不区分大小写的正则匹配 4 !~ 区分大小写不匹配的正则 5 !~* ...
- MyBatis 高级查询之一对多查询(十)
高级查询之一对多查询 查询条件:根据游戏名称,查询游戏账号信息 我们在之前创建的映射器接口 GameMapper.java 中添加接口方法,如下: /** * 根据游戏名查询游戏账号 * @param ...
- protege 构建本体
这里我们使用的是Protégé-OWL规范. 推理机后的内容主要是实操内容,根据推理机来对protege本体模型的一个操作过程,以加深本体模型的一个规范认识. 一.什么是本体(Ontologie) 本 ...
- openresty 学习笔记三:连接redis和进行相关操作
openresty 学习笔记三:连接redis和进行相关操作 openresty 因其非阻塞的调用,令服务器拥有高性能高并发,当涉及到数据库操作时,更应该选择有高速读写速度的redis进行数据处理.避 ...
- 从单一图像中提取文档图像:ICCV2019论文解读
从单一图像中提取文档图像:ICCV2019论文解读 DewarpNet: Single-Image Document Unwarping With Stacked 3D and 2D Regressi ...
- CVPR 2020目标跟踪多篇开源论文(上)
CVPR 2020目标跟踪多篇开源论文(上) 1. SiamBAN:面向目标跟踪的Siamese Box自适应网络 作者团队:华侨大学&中科院&哈工大&鹏城实验室&厦门 ...