✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
🎯 你正在阅读「接口测试从入门到跑路」系列文章 🎯✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
🔥 弹简特 个人主页
❄️ 个人专栏直通车:
✨ 靠热爱去书写自己,靠勇敢去书写生活!
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
🌟 博主简介:

文章目录:
- 前言
- 一、Postman接口鉴权介绍
-
- 1、Cookie鉴权
-
- [1.1 什么是Cookie](#1.1 什么是Cookie)
- [1.2 Cookie里面有哪些键(Key)](#1.2 Cookie里面有哪些键(Key))
- [1.3 Cookie鉴权的原理](#1.3 Cookie鉴权的原理)
- [1.4 Postman里面如何实现Cookie鉴权](#1.4 Postman里面如何实现Cookie鉴权)
- [1.5 案例演示](#1.5 案例演示)
- 2、Session鉴权
-
- [2.1 什么是Session](#2.1 什么是Session)
- [2.2 Session里面一般存什么](#2.2 Session里面一般存什么)
- [2.3 Session鉴权的原理](#2.3 Session鉴权的原理)
- [2.4 Postman里面如何实现Session鉴权](#2.4 Postman里面如何实现Session鉴权)
- [2.5 详解Cookie和Session](#2.5 详解Cookie和Session)
- 3、Token鉴权
-
- [3.1 什么是Token](#3.1 什么是Token)
- [3.2 Token里面一般存什么](#3.2 Token里面一般存什么)
- [3.3 Token鉴权的原理](#3.3 Token鉴权的原理)
- [3.4 Postman里面如何实现Token鉴权](#3.4 Postman里面如何实现Token鉴权)
- [3.5 详解Token](#3.5 详解Token)
- 4、Cookie,Session,Token的区别
- 5、Postman中有的鉴权方式
- 二、Postman接口测试加密实战
-
- 1、接口加密基础
-
- [1.1 为什么需要接口加密](#1.1 为什么需要接口加密)
- [1.2 加密算法分类](#1.2 加密算法分类)
- 2、Postman单向加密
- 3、Postman双向加密
- 4、加密实战小结
- 三、Postman接口测试接口签名实战
-
- 1、什么是Sign签名
- 2、主流Sign签名规则
- 3、在Postman中实操
-
- [3.1 接口描述](#3.1 接口描述)
- [3.2 Sign 签名生成脚本](#3.2 Sign 签名生成脚本)
- 四、Postman接口测试Mock
- 五、补充两个函数
- 六、写在最后
前言
这是 Postman 系列的最后一篇,主要整理接口测试中绕不开的几个知识点:鉴权、加密、签名和 Mock。
前面的笔记已经把 Postman 的基础操作、变量、断言、批量执行都过了一遍,本篇把剩下的鉴权方式对比、常用加密算法的代码实现、Sign 签名的生成逻辑以及 Mock 服务的搭建方法补齐,这样整个 Postman 接口测试的知识体系就完整了,那么我们开始吧~
一、Postman接口鉴权介绍
1、Cookie鉴权
1.1 什么是Cookie
Cookie不是缓存,是服务器生成并保存在客户端的一段文本信息,格式为字典(键值对)。它通常用于在Web项目中维持状态或传递数据,一般记录的是不重要的数据。当客户端第1次访问服务器时,服务器生成Cookie并通过响应头Set-Cookie返回给浏览器,浏览器将其保存;后续客户端再次访问时,会在请求头Cookie中自动带上之前保存的Cookie值。
1.2 Cookie里面有哪些键(Key)

- name:Cookie的名称,用于标识该Cookie。
- value:Cookie的值,存储具体的数据。
- Domain:作用域,指定Cookie可被发送到哪些域名下。
- Path:作用路径,指定域名下的哪些路径可以携带该Cookie。
- Expire :生命周期,用于区分两类Cookie:
- 时间持久级Cookie :设置了明确的过期时间(
Expires或Max-Age),在到期前即使关闭浏览器也会保留,到期后自动失效。 - 会话级Cookie(Session Cookie):未设置过期时间,仅在当前浏览器会话期间有效,关闭浏览器后即被删除。
- 时间持久级Cookie :设置了明确的过期时间(
- Size:大小,指Cookie所占的存储空间大小(通常以字节计)。
1.3 Cookie鉴权的原理
严格来说,Cookie本身不叫鉴权,它最初的设计目的是用于传递和记录统计数据,比如统计访问服务器的次数等不敏感信息。但在实际Web项目中,常通过Cookie携带会话标识(如Session ID)来实现鉴权,其工作流程如下:
- 首次访问生成Cookie :客户端第一次访问服务器时,服务器生成一个带有唯一标识的Cookie,并通过HTTP响应头
Set-Cookie传输到客户端浏览器,浏览器将其保存。 - 后续请求自动携带Cookie :当同一客户端再次访问该服务器时,浏览器会在请求头
Cookie中自动附带之前保存的Cookie值,服务器读取该Cookie即可识别用户或维持会话状态。
1.4 Postman里面如何实现Cookie鉴权
Postman可以充当浏览器的角色,自动处理Cookie。在发送请求时:
- Postman会像浏览器一样,在首次收到
Set-Cookie响应头后,自动存储Cookie。 - 后续向同一域名发送请求时,Postman会自动在请求头
Cookie中携带对应的Cookie值,无需手动设置。
因此,使用Postman进行需要Cookie鉴权的接口测试时,只需要先发送一次带有登录或会话初始化的请求,让Postman获取并保存Cookie,之后对该域名下的其他接口请求便会自动完成Cookie鉴权。
1.5 案例演示
1)首先我们在Postman里面点击Cookies

2)在里面我们现在是看不到任何session的

3)现在我访问论坛首页

4)此时再次打开Cookies看里面,你会看到内容


浏览器也会自动的保存cookie,我们的Postman就是充当浏览器这样的一个角色自动保存的cookie。
5)接下来我们访问登录页面

在后续的请求中,浏览器也会自动带上Cookie值,Postman就是充当浏览器这样的一个角色,自动带上cookie值。
6)总结
总之举例子就是说明对于Postman我们测试人员不用去管 Cookie的存值和传递的过程,他会自动的为我们做这些事。
2、Session鉴权
2.1 什么是Session
Session也叫会话,指的是用户从登录到登出这一完整周期内与服务器之间的交互过程。在技术实现上,它表现为服务器在内存中为用户创建的一个专属数据存储空间。Session一般应用于Web项目,默认失效时间通常是半小时,具体时长由应用服务器决定。
2.2 Session里面一般存什么
Session存储在服务器端,通常用来保存一些需要保密的、与用户当前会话强相关的数据,例如:
- 用户登录状态及唯一标识(如用户ID)。
- 用户名、角色权限等核心身份信息。
- 临时业务数据(如购物车内容、多步骤表单的中间数据)。
2.3 Session鉴权的原理
Session鉴权不能 单独完成,必须配合Cookie一起使用。SessionID本身只是一串唯一标识,它需要通过Cookie作为传输载体在客户端和服务器之间传递。
具体工作流程如下:
- 第一步(登录) :客户端首次登录时,服务器验证用户名密码通过后,会在服务器内存中创建一个Session,其中保存该用户的身份信息,并生成一个唯一的SessionID。然后,服务器通过本次登录请求的响应头
Set-Cookie,将包含此SessionID的Cookie传输到客户端浏览器。 - 第二步(后续访问) :从登录成功后的第2次请求开始,客户端浏览器会根据Cookie的作用域规则,自动在请求头
Cookie中携带包含SessionID的Cookie值。服务器接收到请求后,从中提取SessionID,并与自己内存中存储的Session清单进行对比。如果能找到匹配的有效Session,就读取其中的用户数据,完成身份鉴权。
2.4 Postman里面如何实现Session鉴权
Postman可以充当浏览器的角色,自带Cookie管理机制。利用这一特性,实现Session鉴权的步骤如下:
- 触发登录 :先发送一次正确的登录请求。Postman在收到服务器返回的
Set-Cookie响应头时,会自动将含有SessionID的Cookie储存下来。 - 自动鉴权 :之后对同一域名(Domain)和路径(Path)下的业务接口发送其他请求时,Postman会像浏览器一样,自动在请求头
Cookie中附带上之前存储的SessionID,与服务器端Session进行比对,从而完成无感鉴权,无需测试人员手动处理。
2.5 详解Cookie和Session
对于Cookie和Session的详细解释可以参考博客 👇
Cookie和Session
3、Token鉴权
3.1 什么是Token
Token也叫令牌或鉴权码,是服务器生成并返回给客户端的一串字符串凭证。它通常用于无状态的接口鉴权,由开发人员在后端代码中设定生成规则和时效性(如2小时过期)。与Cookie和Session不同,Token不强制依赖浏览器的存储机制,它本质上是一个需要开发人员在前后端代码中显式处理的凭证。
3.2 Token里面一般存什么
Token(尤其是JWT格式)通常由编码后的字符串构成,其中可能包含:
- 用户的唯一标识(如用户ID)。
- 令牌的签发时间与过期时间。
- 用户角色或权限范围。
- 自定义的业务负载数据。
3.3 Token鉴权的原理
Token鉴权可以独立完成 ,不依赖于Cookie。它是否需要浏览器自动处理,取决于开发人员的实现方式:通常Token由开发人员主动保存在客户端的本地存储(如LocalStorage)或Cookie中,并在每次请求时手动取出附加到请求中。因此,在测试过程中,需要测试人员手动处理。
工作流程如下:
- 第一步(登录获取):客户端提交登录信息,服务器验证通过后生成一个Token,并保存到服务器数据库(或在无状态令牌中直接签发)。服务器会将此Token放在响应体(Body)中返回给客户端。
- 第二步(后续访问):从第2次请求开始,客户端需要主动读取Token,并根据约定的鉴权模式将其附加到请求中进行传输。服务器收到Token后,会与数据库记录对比或解析校验令牌有效性,完成鉴权。
Token鉴权的传输形式(由开发人员定义,测试时需查阅接口文档确认):
- 普通模式 :通过请求参数(Params)传递,如
?token=xxx。 - Bearer模式 :在请求头(Headers)中传输,标准格式为
Authorization: Bearer <token值>。
3.4 Postman里面如何实现Token鉴权
在Token鉴权中,Postman 不能 像处理Cookie那样自动存储和携带Token,需要我们测试人员手动处理。
处理方式依据接口文档而定,主要在Postman的以下位置操作:
- 若接口采用Bearer模式 (最常见):在请求的 Headers 标签页下添加键值对:
- Key :
Authorization - Value :
Bearer+ 空格 + Token的具体值。
(注意:不要错误地写成Authorization Bearer aaaa,这是不规范的格式;标准写法是Authorization: Bearer aaaa,且Bearer作为值的一部分放在Header的Value里。)
- Key :
- 若接口采用普通模式 :在请求的 Params 标签页下添加参数,参数名(如
token)和值按接口文档填写。
操作总结 :测试时,需先调用登录接口并从响应体(Body)中手动复制Token值,然后粘贴到后续业务请求的 Headers 或 Params 中,或者使用我们的提取器将token设置为集合变量等操作,然后从集合变量中去取出。

3.5 详解Token
对于token的各种细节,可以参考博客 👇(总结得很详细,各种原理为你剖析 )
详解token
4、Cookie,Session,Token的区别
结合之前的讲解,将三者的核心区别对比如下:
| 维度 | Cookie | Session | Token |
|---|---|---|---|
| 本质定义 | 存储在客户端的一段小文本信息,格式为字典。 | 存储在服务器内存中的用户会话数据空间。 | 一个由服务器签发的加密字符串令牌。 |
| 存储位置 | 客户端(浏览器)。 | 服务器内存中。 | 通常存于服务器数据库或硬盘中,客户端则存在本地存储(LocalStorage)或Cookie里。 |
| 安全性 | 较低,数据直接暴露在客户端。 | 较高,核心数据在服务器端,客户端只保存一个无意义的SessionID。 | 较高,数据经过编码或加密,即使被截获也难以篡改,但需防范令牌泄露。 |
| 依赖关系 | 独立存在。 | 必须依赖Cookie,SessionID需要通过Cookie在客户端和服务器之间传输。 | 可以独立完成鉴权,不强制依赖Cookie。 |
| 传输方式 | 浏览器根据Domain和Path规则,自动通过Cookie请求头携带。 |
由浏览器通过Set-Cookie和Cookie请求头自动处理,本质上传输的就是SessionID。 |
需要手动处理 ,开发或测试人员需手动将其添加到请求的Params 或Headers (如Authorization)中。 |
| 大小限制 | 有大小限制,单个Cookie不超过4KB。 | 无硬性大小限制,但会话数据过多会大量占用服务器内存,影响性能。 | 无硬性大小限制,但令牌过长会增加每次请求的传输负担。 |
| 生命周期 | • 会话级 :关闭浏览器失效。 • 持久级 :在设置的Expires时间后失效。 |
由应用服务器控制,通常在一段时间无操作后失效(如30分钟)。 | 在签发时设定有效期,在约定的时间后失效(如2小时)。 |
| Postman处理 | Postman能像浏览器一样自动接收和携带,无需测试人员干预。 | Postman能自动处理Cookie,从而实现SessionID的自动携带,无需测试人员干预。 | Postman无法自动处理,需测试人员手动从登录接口响应中复制Token,并根据接口文档粘贴到后续请求的Headers或Params中。 |
总结一下:
- Cookie 是客户端的存储和传输机制,简单但直接。
- Session 将秘密留在服务器,通过Cookie传递一把临时的"钥匙"(SessionID)来鉴权,原生支持浏览器。
- Token 是一张自带信息的加密"身份证",不依赖Cookie和服务器存储,更灵活,尤其适用于前后端分离、移动端或跨域场景,但需要手动处理。
5、Postman中有的鉴权方式

-
Inherit auth from parent:从父节点继承鉴权验证
-
No Auth:没有鉴权
-
Basic Auth:基础验证 使用用户名和密码鉴权的

-
Bearer Token:持有者令牌验证

-
JWT Bearer:JSON Web Token验证

-
Digest Auth:摘要式验证
-
OAuth 1.0:签名过程验证
-
OAuth 2.0:签名过程,类似于Bearer token模式
-
Hawk Authentication:消息验证码验证
-
AWS Signature:亚马逊公有云的验证方式
-
NTLM Authentication:NTLM身份验证
-
API Key:API密钥验证
-
Akamai EdgeGrid:Akamai的边缘网格验证方式
-
ASAP (Atlassian):Atlassian的服务验证协议
二、Postman接口测试加密实战
1、接口加密基础
1.1 为什么需要接口加密
测试接口时,很多敏感数据(比如密码、手机号、支付信息)并不是明文传输的。被测系统为了防止数据被"裸奔"窃取,会要求客户端先按照约定算法加密,再把密文发给服务器。
我们在做接口测试时,95%以上的场景只需要按照算法加密出一条正确的密文,而不用去解密服务器的响应(除非要验证服务器返回的数据是否正确)。也就是说,测试人员主要是在模拟前端的加密行为。
验证加密结果对不对,可以借助在线工具(如 www.bejson.com)来交叉比对。
1.2 加密算法分类
从能不能逆回去的角度,加密算法大致分两类:
-
单向加密(哈希)
只能加密,不能解密。就像一个"指纹机",给同样内容永远产出同样的摘要,但通过摘要无法倒推出原文。
常用于:存密码、文件完整性校验。
代表算法:MD5、SHA系列、HMacSHA系列。
-
双向加密
既能加密,也能解密。根据加/解密用的是不是同一把"钥匙",又分为:
- 对称加密 :加密和解密用同一把密钥 。速度快,但双方都得先知道这个密钥。
代表:Base64(严格说是一种编码)、AES、DES。 - 非对称加密 :有一对钥匙------公钥加密,私钥解密 。公钥可以公开,私钥打死也不给外人。
代表:RSA。Postman 自带的 CryptoJS 库不支持 RSA,需要额外引入脚本。
- 对称加密 :加密和解密用同一把密钥 。速度快,但双方都得先知道这个密钥。
2、Postman单向加密
单向加密直接在 Pre-request Script 里用 CryptoJS 调用,然后存成变量,在请求参数中引用。
在Postman中加密算法都是通过CryptoJS(译为加密 JS 库 )对象来完成的
2.1 MD5加密算法
MD5 生成固定 128 位(即 32 个字符)的哈希值。虽然现在不安全不建议存密码,但老系统中仍广泛使用。
加密算法的代码只需要保存起来,到时候需要的时候粘贴过去就行了,不要刻意去记
MD5加密算法如下:
javascript
// 1. 准备要加密的原始数据
var rawText = "admin";
// 2. 调用 CryptoJS.MD5() 方法进行加密,并用 toString() 转换成十六进制字符串
var md5Hash = CryptoJS.MD5(rawText).toString();
// 结果类似:21232f297a57a5a743894a0e4a801fc3
// 3. 将加密结果存为全局变量,方便在请求参数里 {{md5_username}} 引用
pm.collectionVariables.set("md5_username", md5Hash);
2.1.1 实战练习
1)接口文档
简要描述:
MD5加密接口
请求URL:
http://116.62.63.211:5000/md5login
请求方式:POST
参数:
参数名 必选 类型 说明 备注 username 是 string 用户名:admin 用户名必须MD5加密处理 password 是 string 密码:123 密码必须MD5加密处理 返回示例
java{"error_code":0,"message":"MD5加密登陆成功!"}返回参数说明
参数名 类型 说明 message string success表示登陆成功
2)开始测试
a、如果不加密:请求失败

b、如果加密:首先要在请求之前把admin和123加密好,并存在集合变量中


js
//加密用户名admin
var md5Username = CryptoJS.MD5("admin").toString();
//假面密码123
var md5Password = CryptoJS.MD5("123").toString();
//将结果存到集合变量中
pm.collectionVariables.set("md5_username", md5Username);
pm.collectionVariables.set("md5_password", md5Password);
c、从集合变量中去取出值取值使用{``{名字}}


2.2 SHA系列加密算法
SHA 家族比 MD5 更安全,可以提供更长位数的摘要,比如 SHA-256 就非常常用。
javascript
// 以 "admin" 为例,演示不同 SHA 算法的调用
// SHA1(160位哈希值)
var sha1Hash = CryptoJS.SHA1("admin").toString();
console.log("SHA1:", sha1Hash);
// SHA3(最新标准,可输出不同长度,默认是 512 位)
var sha3Hash = CryptoJS.SHA3("admin").toString();
console.log("SHA3:", sha3Hash);
// SHA224 / SHA256 / SHA384 / SHA512 分别代表不同长度的输出
var sha224Hash = CryptoJS.SHA224("admin").toString();
console.log("SHA224:", sha224Hash);
var sha256Hash = CryptoJS.SHA256("admin").toString();
console.log("SHA256:", sha256Hash);
var sha384Hash = CryptoJS.SHA384("admin").toString();
console.log("SHA384:", sha384Hash);
var sha512Hash = CryptoJS.SHA512("admin").toString();
console.log("SHA512:", sha512Hash);
// 实际使用时,选一个算法即可,把结果存成变量(具体存为什么变量,根据需求来)
pm.collectionVariables.set("sha256_pwd", sha256Hash);
2.3 HMacSHA系列加密算法
HMac 在普通哈希的基础上加了一个密钥,相当于"带密码的哈希"。即使原文相同,密钥不同,结果完全不一样。
javascript
// HMac系列函数的第一个参数是「原文」,第二个参数是「密钥」
var secretKey = "mashang";
// HmacSHA1
var hmacSHA1 = CryptoJS.HmacSHA1("admin", secretKey).toString();
console.log("HmacSHA1:", hmacSHA1);
// HmacSHA256(最常用)
var hmacSHA256 = CryptoJS.HmacSHA256("admin", secretKey).toString();
console.log("HmacSHA256:", hmacSHA256);
// HmacSHA512
var hmacSHA512 = CryptoJS.HmacSHA512("admin", secretKey).toString();
console.log("HmacSHA512:", hmacSHA512);
// 甚至还有 HmacMD5,虽然不推荐但用法一致
var hmacMD5 = CryptoJS.HmacMD5("admin", secretKey).toString();
console.log("HmacMD5:", hmacMD5);
// 把需要的一个结果存入环境变量,也可是集合变量(具体看需求)
pm.environment.set("hmac_sign", hmacSHA256);//存入环境变量
pm.collectionVariables.set("hmac_sign", hmacSHA256);//存入集合变量
3、Postman双向加密
双向加密中,我们不仅要会加密(模拟请求入参),有时候也要能解密(用来断言返回的密文数据)。
3.1 双向对称加密算法
Base64 编码(常被当成加密用)
Base64 其实不是加密,只是一种编码方式,可以把二进制数据转成纯文本。但它"可逆",看起来像加密,老系统里偶尔会用它传密码。
javascript
// ========== 加密 ==========
// 1. 把需要编码的字符串转成 UTF-8 字节数组
var wordBytes = CryptoJS.enc.Utf8.parse("admin");
// 2. 用 Base64 编码该字节数组
var base64Str = CryptoJS.enc.Base64.stringify(wordBytes);
// 结果: "YWRtaW4="
// 3. 存入变量备用
pm.collectionVariables.set("base64_username", base64Str);
// ========== 解密 ==========
// 需要解密时,执行以下步骤
// 1. 将 Base64 字符串解析成字节数组
var decodedBytes = CryptoJS.enc.Base64.parse("YWRtaW4=");
// 2. 把字节数组再转回 UTF-8 字符串
var originalText = decodedBytes.toString(CryptoJS.enc.Utf8);
console.log("解密结果:", originalText); // 输出: admin
AES 对称加密
AES 是真正的加密算法,需要约定好密钥(Key) 、加密模式(如 CBC) 和初始向量(IV)。
javascript
// 定义密钥和初始向量(必须和服务器约定好,且长度通常为16字节)
var key = CryptoJS.enc.Utf8.parse("1234567890123456"); // 16位密钥
var iv = CryptoJS.enc.Utf8.parse("1234567890123456"); // 16位IV
// 调用 AES 加密,传入原文和配置
var encrypted = CryptoJS.AES.encrypt("admin", key, {
iv: iv, // 初始向量
mode: CryptoJS.mode.CBC, // 加密模式(CBC最常用)
padding: CryptoJS.pad.Pkcs7 // 填充方式
}).toString();
// 结果是一长串 Base64 编码的密文,直接存入变量
pm.collectionVariables.set("aes_token", encrypted);
// ========== AES 解密 ==========
// 如果需要解密响应里的密文
var decryptedBytes = CryptoJS.AES.decrypt(encrypted, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
// 解密后是字节数组,转回原文
var decryptedText = decryptedBytes.toString(CryptoJS.enc.Utf8);
console.log("AES解密:", decryptedText); // admin
DES 对称加密
DES 跟 AES 用法类似,只是算法换成了 CryptoJS.DES,密钥长度一般是 8 字节。
javascript
var desKey = CryptoJS.enc.Utf8.parse("12345678"); // 8字节密钥
var desIv = CryptoJS.enc.Utf8.parse("12345678");
var encryptedDES = CryptoJS.DES.encrypt("admin", desKey, {
iv: desIv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}).toString();
pm.collectionVariables.set("des_pwd", encryptedDES);
Base64实战
1)接口文档
简要描述:
BASE64加密接口
请求URL:
http://116.62.63.211:5000/base64login
请求方式:POST
参数:
参数名 必选 类型 说明 备注 username 是 string 用户名:admin 用户名必须BASE64加密处理 password 是 string 密码:123 密码必须BASE64加密处理 返回示例
json{"error_code":0,"message":"Base64加密登陆成功!"}返回参数说明
参数名 类型 说明 message string success表示登陆成功
2)开始测试
a、如果你不加密,那么请求就会报错哦

b、在请求之前使用代码用Base64对admin和123进行加密
代码:
js
/****对于用户名***/
//把需要编码的字符串转成 UTF-8 字节数组
var username = CryptoJS.enc.Utf8.parse("admin");
//用 Base64 编码该字节数组
var base64Username = CryptoJS.enc.Base64.stringify(username);
/****对于密码***/
//把需要编码的字符串转成 UTF-8 字节数组
var password = CryptoJS.enc.Utf8.parse("123");
//用 Base64 编码该字节数组
var base64Password = CryptoJS.enc.Base64.stringify(password);
//将结果存到集合变量中
pm.collectionVariables.set("base64_username", base64Username);
pm.collectionVariables.set("base64_password", base64Password);

c、使用{``{名字}}取出我们加密之后的值

3.2 双向非对称加密算法 ------ RSA(了解即可)
RSA 有一对钥匙:公钥(加密) 和 私钥(解密) 。服务端把公钥给前端,前端用公钥加密后发送,服务端用自己的私钥解开。
但在 Postman 里,CryptoJS 不支持 RSA,不能直接一行代码调用。测试这类接口时,需要测试人员通过以下方式手动处理:
- 引入第三方的 JS 库(如
forge),在 Pre-request Script 中编写更复杂的加密脚本。 - 或者,用 Java/Python 等编写一个本地加解密工具,测试前调用工具生成密文,再粘贴到 Postman 里。
因此 RSA 加密的 Postman 实现并不在"精通"范围内,需要依赖脚本开发能力,所以这个我们就不举例子了,了解即可,我们的Postman不太支持。
4、加密实战小结
| 加密类型 | 算法例子 | 能否解密 | Postman实现方式 | 关键点 |
|---|---|---|---|---|
| 单向加密 | MD5, SHA, HmacSHA | ❌ 不可解密 | 直接调用 CryptoJS.MD5/SHA...,toString()后存变量 |
通常只加密入参;Hmac 需要额外提供密钥 |
| 对称加密 | AES, DES, Base64(编码) | ✅ 可解密 | 调用 CryptoJS.AES/DES.encrypt/decrypt 并配置密钥、IV等 |
注意密钥长度、加密模式和向量;Base64用 enc.Base64 |
| 非对称加密 | RSA | ✅ 可解密(私钥) | CryptoJS 不支持,需引入 forge 等外部库编写脚本 |
需要开发提供公钥,测试时确保用正确的填充格式 |
Postman 加密通用套路:
- 在请求的 Pre-request Script 标签页写加密代码。
- 把密文存入变量,如
pm.environment.set("encryptedPwd", 密文); - 在请求的 Params / Body 里用
{``{encryptedPwd}}占位引用。
三、Postman接口测试接口签名实战
对于接口签名的详细解释,我们在之前的jmeter中介绍过,可参考博客 👇
精通jmeter之接口签名
这里就简单回顾一下👇
1、什么是Sign签名
Sign(签名)并不是一种独立的加密算法,而是由开发人员根据项目需要,自定义的一套参数组合与加密规则。它的作用是把请求中的核心参数,按照约定方式拼成一个字符串,再通过MD5等单向加密生成一个"防伪码"。
服务器收到请求后,会用相同的规则再算一次签名,然后与客户端传来的签名比对。如果不一致,就说明请求在传输过程中被篡改,或者签名秘钥不对,服务器会直接拒绝请求。
为什么需要Sign?
- 防篡改:只要参数有一丁点变动,签名就完全不一样。
- 防重放:签名中通常会加入时间戳和随机数(nonce),让攻击者无法拿同一个请求反复提交。
- 身份识别 :签名前会拼入预先分配好的
appid和appsecret,相当于给请求盖了个"项目章"。
2、主流Sign签名规则
虽然每家公司规则不同,但绝大多数Sign签名都遵循下面这套流程:
第1步:收集所有参数
把请求中的Query参数(?后面的)和Body参数(如表单、JSON)全部拿出来,准备参与签名。
⚠️ 动态参数除外:像
csrf_token、sign、timestamp这些本身就是用于防伪或签名计算的参数,通常不参与签名。
第2步:按键名ASCII码升序排序
把所有参数按照参数名的字母/字符ASCII码从小到大排序。
- 比如原顺序:
{c:3, a:2, b:1} - 排序后变成:
{a:2, b:1, c:3}
第3步:拼接成URL参数字符串
把排序后的参数名和值用 = 连接,参数之间用 & 连接。
- 排序后的集合 →
a=2&b=1&c=3
第4步:在字符串头部拼接 appid 和 appsecret
这两个是项目分配好的身份标识,通常直接拼在最前面。
- 拼接后:
appid=admin&appsecret=123&a=2&b=1&c=3
第5步:在字符串尾部拼接随机数 nonce
nonce 是用来保证请求唯一性的流水号,防止重复提交,一般是一串10位以上的随机字符串。
- 拼接后:
appid=admin&appsecret=123&a=2&b=1&c=3&nonce=1234567890abcdef
第6步:在字符串尾部拼接时间戳 timestamp
时间戳通常精确到秒或毫秒,服务器只接受一定时间范围内的请求(如10分钟内),超时就失效。
- 拼接后:
appid=admin&appsecret=123&a=2&b=1&c=3&nonce=1234567890abcdef×tamp=1683000000
第7步:进行MD5加密,并转为大写
对这个长字符串做一次MD5运算,然后把所有字母转成大写,这就是最终的签名 sign。
- 签名结果类似:
F8E2A1B3C4D5E6F7A8B9C0D1E2F3A4B5
第8步:把 sign 放到请求头中发送
通常放到 Authorization 头或自定义的 Sign 头里,例如:
Sign: F8E2A1B3C4D5E6F7A8B9C0D1E2F3A4B5- 或
Authorization: sign=F8E2A1...
接下里我们将上述的过程写成代码👇
3、在Postman中实操
3.1 接口描述
- 接口地址 :
POST http://127.0.0.1/wind/index.php?m=u&c=login&a=dorun - Body参数 (
x-www-form-urlencoded):username:lisipassword:123456csrf_token:{``{csrf_token}}← 动态参数,不参与签名backurl:http://127.0.0.1/wind/invite: (没填,空值是否参与签名看规则)
假定这个项目的签名规则就是上面说的标准流程,并且约定:
appid=adminappsecret=123(根据实际项目填入)- 签名计算时排除
csrf_token - 最终签名放在请求头
Sign里。
3.2 Sign 签名生成脚本
1、将以下代码完整粘贴到登录接口的 Pre-request Script 标签页。
javascript
// ==================== Sign 签名生成脚本 ====================
// 规则说明:
// 1. 收集所有 Query 参数和 Body 参数(排除 csrf_token 等动态字段)
// 2. 将参数按 key 升序排列
// 3. 拼接为 key=value 的 & 连接字符串
// 4. 在最前面加上 appid=xxx&appsecret=xxx
// 5. 在最后面加上 nonce=随机数×tamp=时间戳
// 6. 整个字符串做 MD5 加密,并转大写,得到 sign
// 7. 把 sign、nonce、timestamp 存入环境变量,供 Headers 使用
// -----------------------------------------------------------
// 【工具函数1】生成指定范围内的随机整数(用于 nonce)
// min:最小值,max:最大值
function getnonce(min,max){
// Math.random() 返回 0-1 之间的随机小数
// 乘以 (max - min + 1) 再 floor,得到一个 [min, max] 的整数
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// 【工具函数2】将对象的 key 按照 ASCII 码升序排序,返回一个新对象
// 这样后续遍历对象拼接字符串时,顺序就是固定的
function objectsort(obj){
// 取出所有 key 并排序
var new_key = Object.keys(obj).sort();
console.log("排序后的 key 顺序:", new_key);
var arr = {}; // 新对象,顺序插入
for(var i=0; i<new_key.length; i++){
// 按排好的 key 依次拷贝 value
arr[new_key[i]] = obj[new_key[i]];
}
return arr;
}
// ===========================================================
// 步骤1:获取项目分配好的 appid 和 appsecret(相当于用户名和密码)
var api_id = "admin";
var api_secret = "123";
console.log("appid:", api_id);
console.log("appsecret:", api_secret);
// ===========================================================
// 步骤2:获取当前时间戳
// 注意:这里原代码用的是 new Date().getTime(),返回的是 13 位毫秒级时间戳
// 很多后端签名校验使用 10 位秒级时间戳,若不一致会导致验签失败
// 建议与开发确认后,如需秒级,改为:Math.floor(new Date().getTime() / 1000)
var timestamp = new Date().getTime();
console.log("当前时间戳(毫秒):", timestamp);
// ===========================================================
// 步骤3:生成订单号 nonce(十位随机数字)
// 作用:保证每次请求的唯一性,防止重放攻击
var nonce = getnonce(1000000000, 9999999999);
console.log("nonce=" + nonce);
// ===========================================================
// 步骤4:收集需要参与签名的所有参数
// 4.1 获取 URL 问号后面的 Query 参数(例如 m=u&c=login&a=dorun)
var params_value = pm.request.url.query.members;
console.log("Query 参数:", params_value);
// params_value 是数组,每个元素形如 {key:"m", value:"u"}
// 4.2 获取 Body 中的参数(x-www-form-urlencoded 格式)
// request.data 在 Pre-request Script 中是已解析好的 body 对象
var body_value = request.data;
// 删除动态字段 csrf_token,因为它每次都会变,不应该参与签名
delete body_value['csrf_token'];
console.log("去除 csrf_token 后的 Body 参数:", JSON.stringify(body_value));
// 4.3 将 Query 参数转换为普通对象,方便合并
var queryObj = {};
if(params_value){
params_value.forEach(function(item){
// 只保留有值且非空的参数(空值不参与签名)
if(item.value){
queryObj[item.key] = item.value;
}
});
}
// 4.4 合并 Query 和 Body 参数(Body 优先级更高,可覆盖同名参数)
var allParams = {};
// 先放入 Query 参数
for(var k in queryObj){
allParams[k] = queryObj[k];
}
// 再放入 Body 参数(有同名的 key 会覆盖)
for(var k in body_value){
// 只保留有值的参数,并且排除可能残留的 sign、timestamp、nonce 等动态字段
var excludeKeys = ['sign', 'timestamp', 'nonce'];
if(body_value[k] && excludeKeys.indexOf(k) === -1){
allParams[k] = body_value[k];
}
}
console.log("合并后的待签名参数:", JSON.stringify(allParams));
// ===========================================================
// 步骤5:将合并后的参数按 key 进行升序排序
var sortedParams = objectsort(allParams);
console.log("排序后的参数:", JSON.stringify(sortedParams));
// ===========================================================
// 步骤6:把排序后的参数拼接成 "key=value&key=value" 格式的字符串
var paramStr = '';
for(var k in sortedParams){
paramStr += k + '=' + sortedParams[k] + '&';
}
// 去掉末尾多余的 &
if(paramStr.endsWith('&')){
paramStr = paramStr.slice(0, -1);
}
console.log("参数字符串:", paramStr);
// ===========================================================
// 步骤7:拼接待签名的完整原始字符串
// 规则:appid=xxx&appsecret=xxx&[参数字符串]&nonce=xxx×tamp=xxx
var rawStr = 'appid=' + api_id + '&appsecret=' + api_secret;
if(paramStr){
rawStr += '&' + paramStr;
}
rawStr += '&nonce=' + nonce + '×tamp=' + timestamp;
console.log("待签名原始串:", rawStr);
// ===========================================================
// 步骤8:计算 MD5 哈希,并转成大写,作为最终签名 Sign
var sign = CryptoJS.MD5(rawStr).toString().toUpperCase();
console.log("生成的 Sign:", sign);
// ===========================================================
// 步骤9:将 sign、nonce、timestamp 存入 Postman 环境变量
// 这样在请求的 Headers 中就可以通过 {{sign}} 等方式引用
pm.environment.set("sign", sign);
pm.environment.set("nonce", nonce);
pm.environment.set("timestamp", timestamp);
console.log("环境变量已设置:sign, nonce, timestamp");


注意:代码直接复制就行,我们也可以问AI辅助我们提效。
2、在 Headers 中添加一行:Key: Sign,Value: {``{sign}}。

四、Postman接口测试Mock
1、什么是Mock
Mock译为模拟,Mock就是模拟数据,Mock 服务,本质上就是通过构造假的接口返回数据,来替代真实的后端响应。这样一来,前端同学在开发功能、搭建模块时,就无需苦等真实接口就绪,可以完全脱离对后端数据的依赖。前后端由此得以同步推进,从而显著缩短整体的项目开发周期。
2、Postman中如何Mock数据
1)第一步:选择Mock服务


2)构造Mock服务

比如Mock数据如下:
js
{
"tags": [
{
"id": 1,
"name": "每天一罐可乐星人",
"count": 0//此标签下粉丝数
},
{
"id": 2,
"name": "星标组",
"count": 0
},
{
"id": 127,
"name": "广东",
"count": 5
}
]
}
3)点击变量可以看到我们构造的请求URL

4)测试获取Mock数据
URL中的ip直接{``{url}}获取

结果:

或者URL路径我们自己复制

结果:

五、补充两个函数
1、时间戳函数
js
// 获取当前时间戳(毫秒级,13位)
// Date.now() 返回从 1970年1月1日 00:00:00 UTC 到当前时刻的毫秒数
var ts = Date.now();
console.log("当前时间戳(毫秒):", ts);
// 如果需要秒级时间戳(10位),除以 1000 后向下取整
var tsSeconds = Math.floor(Date.now() / 1000);
console.log("当前时间戳(秒):", tsSeconds);
2、使得请求等待三秒访问的延时函数
js
// 定义 sleep 函数,参数 milliseconds 表示要等待的毫秒数
const sleep = (milliseconds) => {
// 记录开始等待时的时间戳
const start = Date.now();
// 循环检查当前时间,直到超过预设的等待时长才退出
// 注意:这种写法会阻塞当前线程,但 Postman 沙箱环境允许这样用
while (Date.now() <= start + milliseconds) {}
};
// 调用示例:等待 3 秒(3000 毫秒)
console.log("开始等待 3 秒...");
sleep(3000);
console.log("等待结束,继续执行后续请求");

OK,到此~ 我们的精通Postman也就告一段落了
六、写在最后
兄弟们,到这里咱们 精通 Postman 接口测试就完结撒花了 🌸🌸🌸
从最开始的 Postman 安装配置,到变量体系、请求构建、断言提取,再到本篇的鉴权加密鉴权签名 Mock ------ 一路走过来,咱们把 Postman 接口测试的完整技能树都点亮了。
最后,要感谢每个点赞、评论、催更的兄弟 ------ 没有你们的正反馈,这个系列很难坚持到完结 ❤️
工具会变,但测试思维和方法论不会过时。Postman 的终点不是结束,是我们自动化测试路上的新起点。
下一系列见咯,兄弟们~~

