当前位置: 首页 > 后端技术 > PHP

使用postman调试jwt开发的接口

时间:2023-03-29 17:59:46 PHP

我的github博客:https://zgxxx.github.io/上一篇博文https://segmentfault.com/a/11...介绍了dingo+在laraveljwt开发API的几个步骤,那么在实际运行中,我们需要对API进行测试$api=app('Dingo\Api\Routing\Router');$api->version('v1',['namespace'=>'App\Http\Controllers\V1'],function($api){$api->post('register','AuthController@register');$api->post('login','AuthController@login');$api->post('logout','AuthController@logout');$api->post('refresh','AuthController@refresh');$api->post('me','AuthController@我');$api->get('test','AuthController@test');});设置了这些路由,对应的url类似这样:http://www.yourweb.com/api/me使用postman调试这些API。请求API的一般流程。我们使用jwt而不是session。首先登录(jwt验证账号密码的attempt方法)。成功后会返回一个JWT。我们称这个字符串为标记。此令牌需要由我们的客户保存。然后需要认证的接口会在请求头中带上这个token。后台验证无误后,进行下一步操作。如果令牌错误或过期,将返回401或500错误,并拒绝后续操作。前端可以保存在localStorage,小程序可以使用wx.setStorageSync保存,所以请求头信息Authorization:Bearer+token很重要,但是有个问题,这个token有刷新时间和过期时间:'ttl'=>env('JWT_TTL',60),'refresh_ttl'=>env('JWT_REFRESH_TTL',20160),refresh_ttl是过期时间,默认14天,很好理解,就像一些网站,你几个月没有登录,你的账号会自动注销,因为已经过期,需要重新输入账号密码才能登录。ttl刷新时间默认为60分钟,也就是说,不能使用一小时前的token请求,会报“Thetokenhasbeenblacklisted”的错误,也就是说旧的token已经被列入黑名单,不能再使用token会被别人盗用,所以令牌需要每隔一段时间更新一次。这时候就有问题了。如果每小时更新一次,那岂不是每个小时都需要重新登录才能获得新的token?当然不是,我们可以写一个中间件来无痛刷新token,用户不会注意到我们更新了token。checkForToken($request);//使用try包捕获token过期时抛出的TokenExpiredExceptiontry{//检查用户的登录状态,如果正常则通过if($this->auth->parseToken()->authenticate()){return$下一个($请求);}thrownewUnauthorizedHttpException('jwt-auth','未登录');}catch(TokenExpiredException$exception){//这里捕获过期的token抛出的TokenExpiredException异常,我们这里要做的是刷新用户的token,并添加到响应头中try{//刷新用户的token$token=$this->auth->refresh();//使用一次性登录保证本次请求成功\Auth::guard('api')->onceUsingId($this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray()['sub']);}catch(JWTException$exception){//如果捕获到这个异常,说明刷新也已经过期,用户无法刷新token,需要重新登录。抛出新的UnauthorizedHttpException('jwt-auth',$exception->getMessage());}}return$next($request)->withHeaders(['Authorization'=>'Bearer'.$token,]);}}一旦中间件检测到token过期,它会自动刷新token,然后在响应头中返回新的token。我们的客户端可以根据响应头是否有'Authorization'来决定是否替换token。使用postman调试这些API的时候出现了问题。Postman没有前端代码。我怎样才能及时更新这个令牌?是不是每次请求都要看responseheader,发现Authorization后手动复制粘贴?当然,我不需要它。Postman有一个强大的环境变量其实就是前端js的东西。Postman自动刷新请求头token,登录后自动获取token。首先点击SetEnvironment按钮,点击Add按钮添加一个变量。我们设置key值为access_token,然后我们在登录界面的Tests中给这个变量赋值vardata=JSON.parse(responseBody);if(data.result.access_token){tests["Bodyhastoken"]=true;vartokenArray=data.result.access_token.split("");postman.setEnvironmentVariable("access_token",tokenArray[1]);}else{tests["Bodyhastoken"]=false;}这段js代码是获取请求成功后返回的access_token值,赋值给postman的环境变量。我们看到请求成功后,会在后台返回创建一个json,里面有我们需要的access_token,我们可以去环境变量里面看看这个时候变量发生了哪些变化,我们可以看到这里的变量access_token已经有值了,就是我们后台返回的access_token字符串,说明赋值成功,然后我们去另外一个需要认证的接口进行测试。我们在Authorizationtype类型中选择BearerToken,稍后在Token形式中输入一个'{',它会自动提示我们设置变量{{access_token}}来发送请求以测试是否有效。轻松刷新令牌。如果刷新token,后台中间件无痛刷新后,会在responseheader中返回新的token(此时请求使用旧token,默认认证通过)。现在我们需要使用这个接口直接更新我们的变量access_token(如下图所示)而不是再次请求登录接口varauthHeader=postman.getResponseHeader('Authorization');if(authHeader){vartokenArray=authHeader.split("");邮差。setEnvironmentVariable("access_token",tokenArray[1]);tests["Bodyhasrefreshtoken"]=true;}else{tests["Bodyhasnorefreshtoken"]=false;这段js代码就是响应头中的Authorization分配给我们的access_token就是响应头的Authorization。截取最后一个字符串,刷新时间过后,我们再次尝试发送请求。我们可以看到还是可以访问的,请求头中的Authorization已经自动更新结束了。一句话,你需要更新接口响应后的变量。到这个端口写js赋值代码postman.setEnvironmentVariable("access_token",token);只要没有错误,就可以在其他地方更新和替换为{{access_token}}。