【问题标题】:How to fire an event after successful authentication with JWT使用 JWT 成功认证后如何触发事件
【发布时间】:2020-01-03 18:45:31
【问题描述】:

我有一个 Laravel 版本 6 应用程序。我使用JWT package 进行身份验证。

这样定义的路由:

// route/api.php
Route::middleware('auth:api')->group(function () {
     Route::apiResources([
        'genders' => 'API\GenderController'
    ]);
});

在控制器内部,我有 5 个函数 indexstoreshowupdatedestroy

在这些函数中运行任何代码之前,我需要为当前用户设置语言环境,如下所示:

public function index()
{
     $locale = request()->user()->lang;    
     app()->setLocale($locale);
     // Rest of the function
}

我的控制器类扩展了BaseController 类。由于 Restful API 是无状态的,我需要在每次用户发送 API 请求时设置语言环境。现在的问题是,哪里是最好的地方,我该怎么做?

我尝试在 BaseController 的构造函数中执行此操作,但似乎 middleware('auth:api') 尚未检查构造函数中的令牌。

另一个选项是在身份验证事件处理程序中设置语言环境。我找到了一个 JWT 包事件列表here

// fired when the token could not be found in the request
Event::listen('tymon.jwt.absent');

// fired when the token has expired
Event::listen('tymon.jwt.expired');

// fired when the token is found to be invalid
Event::listen('tymon.jwt.invalid');

// fired if the user could not be found (shouldn't really happen)
Event::listen('tymon.jwt.user_not_found');

// fired when the token is valid (User is passed along with event)
Event::listen('tymon.jwt.valid');

如果有人可以帮助我为tymon.jwt.valid 定义一个处理程序,我将不胜感激。或者即使您有其他解决方案可以在执行indexstoreshowupdatedestroy 函数之前运行事件。

【问题讨论】:

  • 中间件有什么问题?
  • 中间件没有问题。只是在创建目标类的实例后检查令牌。如果我在 index 函数中运行代码,则用户可以访问,因为检查已经完成。但是,如果我在构造函数中执行此操作,则用户为 null 并且它显示令牌尚未检查。

标签: php laravel jwt


【解决方案1】:

您可以在中间件中轻松完成。只需将验证用户身份的中间件放在设置位置的中间件之前。

创建你的路由类并在App\Http\Kernel::$routeMiddleware注册它

然后像这样使用它:

// rouite/api.php

Route::group(['middleware' => ['auth:api', 'locale']], function () {
    Route::apiResources([
        'genders' => 'API\GenderController'
    ]);
});

【讨论】:

  • 您能否进一步澄清您的答案?
  • laravel.com/docs/master/middleware。中间件的概念是它们在您的路由之前执行,您可以在中间件内部授权用户(您这样做),然后将请求传递给下一个中间件或控制器操作本身。中间件是链式的,因此它们会被另一个调用,因此如果您首先检查下一个中间件中的授权,您将在您的请求中拥有授权用户。
【解决方案2】:

我可以在构造函数类中找到一种不同的方式来访问当前用户。 request()->user() 代码在构造函数中返回 null,auth()->user() 即使在构造函数中也返回当前用户。

abstract class BaseController extends Controller
{
    public function __construct() 
    {
        $locale = auth()->user()->lang;
        app()->setLocale($locale);
    }
}

因此,我可以在 BaseController 类中设置语言环境。

但是,我关于使用 JWT 事件的问题是开放的。另外,我想了解更多有关使用中间件的详细信息,正如@patryk-karczmarczyk 在他的回答中所建议的那样。

【讨论】:

    猜你喜欢
    • 2012-12-27
    • 2018-10-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-09
    • 1970-01-01
    • 2018-01-27
    • 2016-06-10
    • 2013-11-09
    相关资源
    最近更新 更多