Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/laravel/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Laravel 为什么与jwt auth的会话时间是从登录时算起的1小时?_Laravel_Jwt Auth - Fatal编程技术网

Laravel 为什么与jwt auth的会话时间是从登录时算起的1小时?

Laravel 为什么与jwt auth的会话时间是从登录时算起的1小时?,laravel,jwt-auth,Laravel,Jwt Auth,在Laravel7后端RESTAPI应用程序中,我使用jwt auth,我在登录时遇到了一个问题 我可以在前端部分工作,但在1小时内我得到了令牌_过期错误 1) 我试图将会议时间设置得更大,但失败了。在开发阶段,我需要一个多小时的会话时间。 继续现场直播,我将设置会议时间30分钟 2) 我预计,从登录用户的最后一个请求到后端的会话时间是1小时,但不是从登录开始 我在下面实现了刷新方法,但看起来刷新不起作用 app/Http/Controllers/API/AuthController.php:

在Laravel7后端RESTAPI应用程序中,我使用jwt auth,我在登录时遇到了一个问题 我可以在前端部分工作,但在1小时内我得到了令牌_过期错误

1) 我试图将会议时间设置得更大,但失败了。在开发阶段,我需要一个多小时的会话时间。 继续现场直播,我将设置会议时间30分钟

2) 我预计,从登录用户的最后一个请求到后端的会话时间是1小时,但不是从登录开始

我在下面实现了刷新方法,但看起来刷新不起作用

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');
    }
我有:

"laravel/framework": "^7.0",
"tymon/jwt-auth": "^1.0.0",
我的配置有什么问题

已修改:

我添加了一个文件 app/Http/Middleware/JwtMiddleware.php,包含内容和一行错误日志:

<?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/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);
以及从$refreshed写入新的访问令牌值? 但是我怎么能抓住它呢?但是一些特殊的退货要求代码

谢谢

  • 您需要添加中间件并检查令牌是否过期
  • 如果过期,请检查生成时间,以检查是否应生成新令牌。将此视为刷新令牌过期时间。如果要在不进行任何时间验证的情况下生成刷新令牌,可以跳过此步骤
  • 现在,如果一切正常,则生成一个新的令牌,并根据需要将其发送到标头/正文中,并将其存储在前端应用程序中
  • 您需要添加中间件并检查令牌是否过期
  • 如果过期,请检查生成时间,以检查是否应生成新令牌。将此视为刷新令牌过期时间。如果要在不进行任何时间验证的情况下生成刷新令牌,可以跳过此步骤
  • 现在,如果一切正常,则生成一个新的令牌,并根据需要将其发送到标头/正文中,并将其存储在前端应用程序中

在登录时尝试此操作

if ($token = $this->guard('api')->attempt($credentials,['exp' => Carbon\Carbon::now()->addHours(2)->timestamp])) {

}
或者您可以在
config/jwt


如果有帮助,请告诉我

在登录时尝试此操作

if ($token = $this->guard('api')->attempt($credentials,['exp' => Carbon\Carbon::now()->addHours(2)->timestamp])) {

}
或者您可以在
config/jwt

如果有帮助,请告诉我

转到-->config/jwt.php 你可以这样做

'ttl' => env('JWT_TTL', 1440)
或在控制器中

$token = JWTAuth::attempt($credentials, ['exp' => Carbon\Carbon::now()->addDays(7)->timestamp]);

转到-->config/jwt.php 你可以这样做

'ttl' => env('JWT_TTL', 1440)
或在控制器中

$token = JWTAuth::attempt($credentials, ['exp' => Carbon\Carbon::now()->addDays(7)->timestamp]);


您应该有一个
config/jwt.php
文件。如果还没有,请运行:

php artisan供应商:publish--provider=“Tymon\JWTAuth\Providers\LaravelServiceProvider”
在该文件中,您可以看到引用
.env
变量的几个属性,它们是:

  • ‘ttl’(环境=‘JWT_ttl’)
  • '刷新\u ttl'(env='JWT\u刷新\u ttl')
另外,您可能希望将
'refresh'
添加到
jwt.auth
中间件异常列表中,因为在控制器中调用
refresh()
函数时,它将不起作用

但是,在这个软件包中有一些重要的东西需要注意:

身份验证TTL链接在一起 我相信您几乎可以忽略
ttl
属性,因为它是
refresh\u ttl
,根据这个类比,它实际上定义了JWT的有效期:

锁匠(认证提供者)给你一把红色钥匙(JWT)。该键允许您打开红门(使用后端)。5分钟(TTL=5分钟)后,钥匙自动对折。但是,您可以带着损坏的钥匙回到锁匠那里,锁匠将在2周内更换钥匙(刷新TTL=2w)

您基本上可以使用过期的JWT调用
auth/refresh
端点,它将刷新端点,直到刷新TTL过期

另请参见[github上的这个问题][1],这也解释了为什么需要添加
refresh
函数,使其前面没有
jwt.auth
中间件

使用此包提供的JWT时,您不会保存任何DB调用 我最初的想法是,它可以节省到数据库的往返时间,因为用户对象将在JWT中签名并准备就绪

我现在已经在几个项目中使用了这个包,我得出的结论是,它有点像一个美化的会话cookie。在
tymon/jwt
中,
sub
声明仅等于
1
(或此处引用的任何用户ID)

这意味着你需要

  • 。。。(默认)让
    tymon/jwt
    做一些简单的工作,从数据库中检索用户并将其应用到您的身份验证提供者,这样
    auth::user()
    等就可以工作了

  • 。。。使用完整用户对象添加声明,并在不同位置修改此包。这可以节省DB调用,因为此对象将是JWT的一部分,并在JWT中签名。它会导致在每次请求时发送更多的JWT字节,但您基本上可以将给定对象视为理所当然(即,在接收时接受它)并使用它。然后还可以通过这种方式添加权限/角色,这样就不需要从数据库中检索这些权限/角色。这个设置确实意味着在更改数据库中的任何权限时,您必须等待刷新新的JWT才能看到这些更改
    $token = JWTAuth::attempt($credentials, ['exp' => Carbon\Carbon::now()->addDays(7)->timestamp]);
    
    config()->set('jwt.ttl', 60*60*7);
    
    Config::set('jwt.ttl', 60*60*7);
    
    // ...
    'ttl' => env('JWT_TTL', 3600)
    
    php artisan config:clear