My Github blog is zgxxx.github. IO /

Previous blog post juejin.cn/post/684490… Having introduced a few steps for Laravel to develop the API using Dingo + JWT, we need to test the API in practice

$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');
});
Copy the code

The routes are set up with urls like: www.yourweb.com/api/me use postman to debug the apis.

The rough flow of the request API

We use JWT instead of session. First, we log in (JWT’s Attempt method is used to verify the account password). After successful login, a JWT will be returned. If the token is incorrect or expired, an error of 401 or 500 will be returned and the subsequent operation will be rejected.

The front end can be saved in localStorage, and small programs can be saved using wx.setStoragesync

So Authorization:Bearer + tokens are important but have a refresh time and expiration date: ‘ttl’ => env(‘JWT_TTL’, 60), ‘refresh_ttl’ => env(‘JWT_REFRESH_TTL’, 20160),

  • Refresh_ttl is the expiration time, the default time is 14 days. It is easy to understand, just like some websites, if you have not logged in for several months, your account will automatically log out, because the expired, you need to re-enter the account password to log in.
  • The default TTL refresh time is 60 minutes, which means that you can’t request The token one hour ago. The token has been blacklisted, which means that The old token has been blacklisted and cannot be used

Tokens can be stolen, so they need to be renewed every once in a while

The question is, if you update every hour, don’t you have to log in again every hour to get a new token? Of course not, we can write middleware to implement painless refreshing token, users will not know we have updated the token.


      

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)
    {
        // Check if there is a token in this request and throw an exception if there is no token.
        $this->checkForToken($request);

        // Use the try package to catch a TokenExpiredException thrown by token expiration
        try {
            // Check the login status of the user. If the status is normal, the user passes
            if ($this->auth->parseToken()->authenticate()) {
                return $next($request);
            }
            throw new UnauthorizedHttpException('jwt-auth'.'Not logged in');
        } catch (TokenExpiredException $exception) {
            // We caught a TokenExpiredException thrown by the token expiration. What we need to do here is refresh the user's token and add it to the response header
            try {
                // Refresh the user's token
                $token = $this->auth->refresh();
                // Use a one-time login to ensure the success of the request
                \Auth::guard('api')->onceUsingId($this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray()['sub']);
            } catch (JWTException $exception) {
                // If this exception is caught, refresh is also expired and the user cannot refresh the token and needs to log in again.
                throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage()); }}return $next($request)->withHeaders([
                'Authorization'= >'Bearer '.$token, ]); }}Copy the code

Once the middleware detects that the token is out of date, it automatically refreshes the token and then returns the new token in the response header. Our client can decide whether to replace the token based on the Authorization of the response header. There is a problem when debugging these apis using Postman. Postman does not have front-end code, how can I update this token in time, do I have to look at the response header every time I request, and find that the Authorization manual copy paste, of course not necessary, Postman has a powerful environment variable, in fact, is the front-end JS things.

Postman automatically refreshes request header tokens

The token is automatically obtained after login

First of all, I’m gonna go ahead and click on the Set environment button, I’m gonna go ahead and Add a variable, and I’m gonna set the key to access_token,

var data = JSON.parse(responseBody);  
if (data.result.access_token) {  
      tests["Body has token"] = true;  
      var tokenArray = data.result.access_token.split("");
      postman.setEnvironmentVariable("access_token", tokenArray[1]);  
}  
else {  
  tests["Body has token"] = false;  
}  
Copy the code

This js code is the access_token value returned after the request is successful, and it is assigned to the environment variable of Postman. We see that after the request is successful, we return a JSON in the background, which contains the access_token we need. We can go to the environment variable to see how the variable changes at this time

Then we go to another interface that requires authentication. We select Bearer Token under the Authorization type. Typing a ‘{‘ in the Token form will automatically prompt us to set the variable {{access_token}}.

Refresh token painlessly

If the token is refreshed, it will be painlessly refreshed by the background middleware, and a new token will be returned in the response header (this time the request uses the old token, which is approved by default)

var authHeader = postman.getResponseHeader('Authorization');
if (authHeader){
      var tokenArray = authHeader.split("");
      postman.setEnvironmentVariable("access_token", tokenArray[1]);  
      tests["Body has refreshtoken"] = true;  
} else {
       tests["Body has no refreshtoken"] = false;  
}
Copy the code

This js code is the access_token that assigns the Authorization in the response header to us

Sorting is probably in one sentence, you need to update after which interface response variables, go to the to write js assignment code under the Test of the postman. The setEnvironmentVariable (” access_token “, token); As long as there are no errors, you can use the {{access_token}} update elsewhere.