引入问题
最近在用 Postman 做服务调试的时候,遇到个场景:需要调试的接口特别多,在发请求的时候都需要带真实有效的AT,我们这边的AT有效期使用默认的十分钟,因为调试的过程中经常会遇到别的事情,导致AT经常失效,花了大量的时候去拿可用的AT,这对于一个懒人来说是不可接受的,下面就介绍一下我是如何一步一步的来解决这个问题的:
阶段一
服务使用的是标准的oauth2鉴权,所以初始的时候最基础能想到的方式就是:先获取 code,然后使用 code 换 AT
通过这种方式获取AT的同学都知道有多痛苦:
- 打开登录界面
- 登录成功之后获取到code
- 截取到code之后去拼接获取token的请求
看似简单的三步太容易出错,对于动不动失效的AT来说是不可忍受的
阶段二
受不了 code 换 AT 之后,想到我们在每次code获取AT的同时,还会获取到RT,用RT去刷AT岂不是更方便?
到这一阶段之后会大大的减少因获取AT而消耗的时间
阶段三
想到RT刷AT的方式之后,自然而然的想到将这个获取的请求写到Postman里,这样过期了之后我只需要找到这个请求点一下即可
解决问题
后来无意中发现了 pre-request
这个异常强大的功能,此功能的目的就是字面意思:在请求之后做一些事情。
那我是不是可以借这个 hook 的特性来更优雅的解决上面的问题呢?当然可以:
我建了一个集合 (collecction),将该服务的所有请求都放到这个集合中,然后通过集合的 pre-request
在每次请求前都去获取下AT,然后注入到集合的变量中,并且刷新RT,这样RT和AT都会刷新,再也不会过期了,而且再也不用考虑AT的问题了。
Postman相关特性介绍
-
变量:postman 中有变量的概念,我们可以给管理变量,然后在请求的时候通过双大括号取用
{{varibale}}
。Postman 也预置了很多内置的变量,为我们模拟请求提供了很大的变量,比如:{{$timestamp}}
;{{$guid}}
、{{$randomUUID}}
等等,可以参考 Dynamic variables -
集合:postman 中提供了作用域的概念,集合可以用来汇聚一类服务,比如都对某一个服务的多个请求
-
pm
对象:包含与当前正在执行的脚本的所有信息,可以用它来操作变量,甚至是用脚本的方式发送一个请求
所以我们可以这么做:
集合环境变量:
增加 pre-request 脚本,每次请求前都会去重置 RT和AT
// 集合的 pre-request
// // 预刷新 USER_AT, USER_RT
const tokenUrl = pm.collectionVariables.get("TOKEN_URL")
const userRT = pm.collectionVariables.get("USER_RT")
const req = {
url: `${tokenUrl}/oauth/token`,
method: 'POST',
header: 'Content-Type: application/x-www-form-urlencoded',
body: {
mode: 'raw',
raw: `grant_type=refresh_token&refresh_token=${userRT}&client_id=hw&client_secret=hw#edc123`
}
}
pm.sendRequest(req, (err, res) => {
if(err) {
console.error(err)
} else {
const resJson = res.json();
pm.collectionVariables.unset("USER_RT")
pm.collectionVariables.set("USER_RT", resJson.refresh_token) // 更新 RT
pm.collectionVariables.unset("USER_AT")
pm.collectionVariables.set("USER_AT", resJson.access_token) // 更新AT
}
})
总结
上文只是用了 pre-request
能力实现的一个很小的诉求,我们可以将postman的很多能力配合使用为我们调试解决很多重复劳动。
Postman更多的能力可以参见它的官网文档,强大超出想象…