使用postman调试jwt开发的接口

laravel使用dingo+jwt开发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@me');
    $api->get('test', 'AuthController@test');
});

请求API的大致流程

我们使用jwt代替session,首先是通过登录(jwt的attempt方法验证账号密码),成功后会返回一个JWT,我们把这个字符串统一叫做token,这个token需要我们客户端保存起来,然后后面需要认证的接口就在请求头里带上这个token,后台验证正确后就会进行下一操作,如果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去请求是不行的,会报The token has been blacklisted的错误,意思是说这个旧的token已经被列入黑名单,无法使用

    token是会被别人盗取的,所以token需要每隔一段时间就更新一次

这时候有个问题,每隔一小时就更新,那岂不是要每小时就重新登录一遍来获取新token?当然不需要,我们可以写个中间件来实现无痛刷新token,用户不会察觉我们已经更新了token。

<?php

namespace App\Http\Middleware;

use Closure;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;

class RefreshToken extends BaseMiddleware
{
    /**
     * @author: zhaogx
     * @param $request
     * @param Closure $next
     * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Response|mixed
     * @throws JWTException
     */
    public function handle($request, Closure $next)
    {
        // 检查此次请求中是否带有 token,如果没有则抛出异常。
        $this->checkForToken($request);

        // 使用 try 包裹,以捕捉 token 过期所抛出的 TokenExpiredException  异常
        try {
            // 检测用户的登录状态,如果正常则通过
            if ($this->auth->parseToken()->authenticate()) {
                return $next($request);
            }
            throw new UnauthorizedHttpException('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) {
                // 如果捕获到此异常,即代表 refresh 也过期了,用户无法刷新令牌,需要重新登录。
                throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage());
            }
        }

        return $next($request)->withHeaders([
                'Authorization'=> 'Bearer '.$token,
            ]);
    }
}

一旦中间件检测到token过时了,就自动刷新token,然后在响应头把新的token返回来,我们客户端可以根据响应头是否有’Authorization’来决定是否要替换token
在使用postman调试这些API的时候就有个问题,postman又没有前端代码,我怎么及时更新这个token,难道每次请求都要去看响应头,发现Authorization后手动去复制黏贴吗,当然也不需要,postman有个强大的环境变量,其实也是前端js的东西。

 

«

发表评论

电子邮件地址不会被公开。 必填项已用*标注

昵称 *