мой блог на гитхабе:zgxxx.github.io/
предыдущий пост в блогеnuggets.capable/post/684490…Введено несколько шагов для 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');
});
Эти маршруты установлены, и соответствующие URL-адреса аналогичны этому:www.yourweb.com/api/meИспользуйте postman для отладки этих API.
Общий процесс запроса API
Мы используем jwt вместо сеанса. Первый — войти в систему (метод попытки jwt для проверки пароля учетной записи), и после успеха будет возвращен JWT. Мы называем эту строку токеном. Этот токен должен быть сохранен нашим клиентом , а затем необходимо пройти аутентификацию позже. Интерфейс переносит этот токен в заголовок запроса. После того, как фоновая проверка будет выполнена правильно, будет выполнена следующая операция. Если токен неверен или срок его действия истек, будет возвращена ошибка 401 или 500, и последующая операция будет отклонена.
Внешний интерфейс можно сохранить в localStorage, а апплет можно сохранить с помощью wx.setStorageSync.
Таким образом, информация заголовка запроса Authorization: Bearer + token очень важна, но есть проблема, у этого токена есть время обновления и время истечения срока действия:'ttl' => env('JWT_TTL', 60),
'refresh_ttl' => env('JWT_REFRESH_TTL', 20160),
- Refresh_ttl - время истечения срока действия, по умолчанию это 14 дней, что легко понять. Как и на некоторых веб-сайтах, если вы не заходили в систему в течение нескольких месяцев, ваша учетная запись автоматически выйдет из системы. Поскольку срок ее действия истекает, вам необходимо повторно -введите учетную запись и пароль для входа.
- Время обновления ttl по умолчанию составляет 60 минут, что означает, что вы не можете использовать токен час назад, чтобы запросить его, и будет сообщено об ошибке Токен был занесен в черный список, что означает, что старый токен был занесен в черный список и не может быть использован.
Токен будет украден другими, поэтому его необходимо время от времени обновлять.
На данный момент есть проблема, он обновляется каждый час, так почему бы не авторизоваться снова каждый час, чтобы получить новый токен? Конечно нет, мы можем написать middleware для безболезненного обновления токена, и пользователь не заметит, что мы обновили токен.
<?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,
]);
}
}
Как только промежуточное ПО обнаруживает, что токен устарел, оно автоматически обновляет токен, а затем возвращает новый токен в заголовке ответа.Наш клиент может решить, следует ли заменить токен в зависимости от того, есть ли в заголовке ответа «Авторизация» или нет. При использовании postman для отладки этих API возникает проблема.Postman не имеет клиентского кода.Как я могу вовремя обновить этот токен?Должен ли я читать заголовок ответа каждый раз, когда я делаю запрос, и копировать и вставлять его вручную после нахождения авторизации?Конечно, нет, у почтальона есть мощная переменная окружения, которая на самом деле является интерфейсной вещью js.
почтальон автоматически обновляет токен заголовка запроса
Автоматически получать токен после входа в систему
Сначала нажмите кнопку, чтобы установить среду, нажмите кнопку «Добавить», чтобы добавить переменную, мы устанавливаем значение ключа в access_token,
Затем мы назначаем эту переменную в Tests интерфейса входа в систему.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;
}
Этот код js предназначен для получения значения access_token, возвращаемого после успешного запроса, и присвоения его переменной окружения postman.Мы видим, что после успешного запроса мы возвращаем json в фоновом режиме, который содержит нужный нам access_token, мы можем перейти к переменной среды Там, чтобы увидеть, какие изменения в переменных в это время
Вы можете видеть, что переменная access_token здесь уже имеет значение, которое представляет собой строку access_token, возвращаемую нашим фоном, что указывает на то, что назначение выполнено успешно.Затем переходим к очередному тесту интерфейса, который требует сертификации Мы выбираем Bearer Token в типе авторизации, и при вводе '{' в форме Token автоматически запрашивается переменная {{access_token}}, которую мы установили.
отправить запрос тестабыл успешным.Токен безболезненного обновления
Затем, если токен обновляется, после безболезненного обновления фонового промежуточного программного обеспечения в заголовке ответа будет возвращен новый токен (на этот раз запрос использует старый токен, а аутентификация по умолчанию проходит)
Теперь нам нужно обновить нашу переменную access_token непосредственно в этом интерфейсе (как показано ниже) без повторного запроса интерфейса входа в систему.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;
}
Этот код js предназначен для назначения авторизации в заголовке ответа нашему access_token
Это авторизация заголовка ответа, перехватывающая последнюю строкуПо истечении времени обновления пытаемся снова отправить запрос, видим, что он по-прежнему доступен, а Авторизация в заголовке запроса автоматически обновилась.В одном предложении, вероятно, вам нужно обновить переменную, после которой интерфейс отвечает, а затем перейти к тесту этого порта, чтобы написать код назначения jspostman.setEnvironmentVariable("access_token", token);
, если нет ошибок, вы можете использовать {{access_token}} для обновления и замены в другом месте.