В приложении laravel 7 backend rest api я использую jwt-auth, и у меня проблема, что при входе в систему я могу работать во фронтенд-части, но через 1 час у меня возникла ошибка TOKEN_EXPIRED.
1) Я попробовал установить время сеанса больше, но не удалось. На стадии разработки мне нужно время сеанса более 1 часа. Двигаясь в прямом эфире, я установлю время сеанса 30 минут.
2) Я ожидал, что сеанс больше на 1 час от последнего запроса зарегистрированного пользователя к бэкэнду, но не от входа в систему
У меня есть refre sh метод реализован ниже, но выглядит как refre sh не работает ...
app / Http / Controllers / API / AuthController. php:
<?php
namespace App\Http\Controllers\API;
use App\library\CheckValueType;
use App\Settings;
use Auth;
use Config;
use DB;
use Validator;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\User;
use Illuminate\Support\Str;
use App\UserGroup;
use App\Http\Resources\UserCollection;
use Avatar;
use Storage;
class AuthController extends Controller
{
/**
* Create a new AuthController instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('jwt.auth', ['except' => ['login', 'register', 'activate']]);
}
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if ($token = $this->guard('api')->attempt($credentials)) {
$loggedUser = $this->guard('api')->user();
if ($loggedUser->status != 'A') {
return response()->json(['error' => 'Unauthorized'], HTTP_RESPONSE_NOT_UNAUTHORIZED);
}
$loggedUser->last_logged = Carbon::now(config('app.timezone'));
$loggedUser->save();
$userGroupsCount = UserGroup
::getByUserId($loggedUser->id)
->count();
if ($userGroupsCount == 0) {
return response()->json(['error' => 'Unauthorized'], HTTP_RESPONSE_NOT_UNAUTHORIZED);
}
return $this->respondWithToken($token);
}
return response()->json(['error' => 'Unauthorized'], HTTP_RESPONSE_NOT_UNAUTHORIZED);
}
public function me()
{
return response()->json($this->guard('api')->user());
}
public function logout()
{
$this->guard('api')->logout();
return response()->json(['message' => 'Successfully logged out']);
}
public function refresh()
{
return $this->respondWithToken($this->guard()->refresh());
}
protected function respondWithToken($token)
{
$loggedUser = $this->guard()->user();
$user_avatar_path = 'public/' . User::getUserAvatarPath($loggedUser->id, $loggedUser->avatar);
$filenameData = User::setUserAvatarProps($loggedUser->id, $loggedUser->avatar, true);
$usersGroups = User::getUserGroupByUserId($loggedUser->id, false);
return response()->json([
'access_token' => $token,
'user' => $loggedUser,
'token_type' => 'bearer',
'user_avatar_path' => $user_avatar_path,
'filenameData' => $filenameData,
'usersGroups' => $usersGroups,
'expires_in' => $this->guard('api')->factory()->getTTL() * 999360 // I SET VERY BIG VALUE
]);
}
public function guard()
{
return \Auth::Guard('api');
}
В /config/auth.php:
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
'hash' => false,
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 99360, // I SET BIG VALUE
'throttle' => 98860,
],
],
'password_timeout' => 10800, // I SET BIG VALUE
В приложении / Исключениях / Обработчик. php У меня есть:
public function render($request, Throwable $exception)
{
if ($exception instanceof UnauthorizedHttpException) {
if ($exception->getPrevious() instanceof TokenExpiredException) {
\Log::info( '-2 UnauthorizedHttpException TokenExpiredException::' ); // I SEE THIS ERROR LOGGED
return response()->json(['error' => 'TOKEN_EXPIRED'], $exception->getStatusCode());
У меня:
"laravel/framework": "^7.0",
"tymon/jwt-auth": "^1.0.0",
Что не так в моей конфигурации?
ИЗМЕНИТЬ:
Я добавил файл app / Http / Middleware / JwtMiddleware. php с содержимым и 1 строкой ошибки ведение журнала:
<?php
namespace App\Http\Middleware;
use Closure;
use Tymon\JWTAuth\Exceptions\JWTException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
class JwtMiddleware extends BaseMiddleware
{
public function handle($request, Closure $next)
{
try {
if (! $user = $this->auth->parseToken()->authenticate()) {
return response()->json(['success' => false, 'error' => __('Invalid User.')]);
}
} catch (TokenExpiredException $e) {
try {
$refreshed = $this->auth->refresh($this->auth->getToken());
$user = $this->auth->setToken($refreshed)->toUser();
header('Authorization: Bearer ' . $refreshed);
} catch (JWTException $e) {
return response()->json(['success' => false, 'error' => __('Could not generate refresh token')]);
}
} catch (JWTException $e) {
\Log::info( '-1 JwtMiddleware$e->getMessage() ::' . print_r( $e->getMessage(), true ) );
return response()->json(['success' => false, 'error' => __('Invalid request')]);
}
return $next($request);
}
}
и я добавил в файл app / Http / Kernel. php:
...
protected $middleware = [
\Fruitcake\Cors\HandleCors::class,
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\App\Http\Middleware\JwtMiddleware::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class
];
...
and running the page site is broken and I see lines in log :
[2020-05-27 17:08:33] local.INFO: -1 JwtMiddleware$e->getMessage() ::The token could not be parsed from the request
[2020-05-27 17:08:33] local.INFO: -1 JwtMiddleware$e->getMessage() ::The token could not be parsed from the request
[2020-05-27 17:08:33] local.INFO: -1 JwtMiddleware$e->getMessage() ::The token could not be parsed from the request
Может быть какой-то конфликт с кодом app / Http / Controllers / API /AuthController.php? Как это исправить?
ИЗМЕНЕНО # 2: Спасибо! Я исправил ошибку и в .env добавил строки:
JWT_TTL=20 # 20 minutes
JWT_REFRESH_TTL=20160 # 2 weeks
и очистив кеш, я снова вошел в систему, и в результате во время работы в приложении я не выходил из системы через 20 минут, но когда я оставил приложение открытым не работая с ним в течение примерно 30 минут, я мог бы продолжить работу без выхода из системы, как я и ожидал. Есть ли другие варианты?
ИЗМЕНЕНО # 3: В клиентской части моего файла vuejs я предпочитаю перехватчики запросов в src / App. vue:
created() {
let self = this
this.$http.interceptors.response.use(undefined, function (error) {
return new Promise(function (/*resolve, reject*/) {
if (typeof error.response.status !== 'undefined' && error.response.status === 401) {
self.$store.dispatch('logout') // DEBUGGING
self.showPopupMessage('Access', 'Not authorized !', 'warn')
let splitted0 = self.getSplitted(error.response.config.url, '/login', 0)
if (splitted0 == '') { // not move from login page
self.$router.push('/login') // DEBUGGING
}
}
if (typeof error.response.status !== 'undefined') {
if (error.response.status === 401) {
self.$store.dispatch('logout') // DEBUGGING
self.showPopupMessage('Access', 'Not authorized !', 'warn')
self.$router.push('/login') // DEBUGGING
}
}
throw error
})
})
}, // created() {
Я ловлю в нем ошибку 401 и задаюсь вопросом, можно ли перехватить запрос с сервера
header('Authorization: Bearer ' . $refreshed);
и записать новое значение access_token из $ refreshed? Но как его поймать? Но какой-то специальный код запроса на возврат?
Спасибо!