当前位置: 首页 > 知识库问答 >
问题:

使用Laravel JWT身份验证的注销问题

凤修为
2023-03-14

我正在使用jwt auth在我的API中创建RESTful身份验证资源。当客户端应用程序调用登录资源时,如果用户已登录,则必须使当前令牌无效,从而生成新令牌。

但如果当前令牌被列入黑名单,则会抛出TokenBlacklistedException

如何验证令牌是否被列入黑名单?或者如何正确执行用户“注销”?我试图在jwt auth API源代码上找到,但不存在getToken()-

Ever token is invalid parseToken()引发TokenBlacklistedException,因此IsBlackList方法是在使令牌无效之前验证令牌是否有效的好方法。

信息:

下面的代码验证有效负载是否无效,如果无效则抛出TokenBlacklistedException

if(
    false === \Tymon\JWTAuth\Blacklist::has(
        \Tymon\JWTAuth\Facades\JWTAuth::getPayload($token)
    )
) {
     \Tymon\JWTAuth\Facades\JWTAuth::parseToken()->invalidate();
}

如何验证,如:

if(false ===\Tymon\JWTAuth\Facades\JWTAuth::parseToken()->isBlacklisted()) {
    // invalidate...
}

共有3个答案

东方森
2023-03-14

据我所知,没有人强调的一件事是用于刷新令牌的“jwt.refresh”(又名刷新令牌中间件)。

现在,如果任何想要执行注销操作的人都将控制器方法包装在如下路径中

Route::group(['middleware' => ['jwt.auth', 'jwt.refresh']], function()...

肯定会在注销响应中获得一个新的令牌,因此客户端将能够执行新的请求。

希望这有助于澄清这个问题。

别浩漫
2023-03-14

这对我有用。

public function logout( Request $request ) {

        $token = $request->header( 'Authorization' );

        try {
            JWTAuth::parseToken()->invalidate( $token );

            return response()->json( [
                'error'   => false,
                'message' => trans( 'auth.logged_out' )
            ] );
        } catch ( TokenExpiredException $exception ) {
            return response()->json( [
                'error'   => true,
                'message' => trans( 'auth.token.expired' )

            ], 401 );
        } catch ( TokenInvalidException $exception ) {
            return response()->json( [
                'error'   => true,
                'message' => trans( 'auth.token.invalid' )
            ], 401 );

        } catch ( JWTException $exception ) {
            return response()->json( [
                'error'   => true,
                'message' => trans( 'auth.token.missing' )
            ], 500 );
        }
    }
颛孙飞
2023-03-14

您可以在客户端注销时简单地销毁会话,并在后端使令牌无效,您不应该需要使用黑名单。

从技术上讲,在客户端销毁令牌就足够了,但是对于会话劫持,在后端使其无效也是一个好主意。

如果您无效,您需要在从Laravel获得响应后销毁令牌。


     JWTAuth::invalidate(JWTAuth::getToken());

然后在有角度的一边

function logout()
{ 
    UserService.logout().$promise.then(function() {
        $cookieStore.remove('userToken');
        // redirect or whatever 
    });
}

处理JWT异常的一种方法是在laravel中设置一个EventServiceProvider,下面是我的示例:

use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider {

    /**
     * The event handler mappings for the application.
     *
     * @var array
     */
    protected $listen = [
        'tymon.jwt.valid' => [
            'App\Events\JWTEvents@valid',
        ],
        'tymon.jwt.user_not_found' => [
            'App\Events\JWTEvents@notFound'
        ],
        'tymon.jwt.invalid' => [
            'App\Events\JWTEvents@invalid'  
        ],
        'tymon.jwt.expired' => [
            'App\Events\JWTEvents@expired'  
        ],
        'tymon.jwt.absent' => [
            'App\Events\JWTEvents@missing'
        ]
    ];

    /**
     * Register any other events for your application.
     *
     * @param  \Illuminate\Contracts\Events\Dispatcher  $events
     * @return void
     */
    public function boot(DispatcherContract $events)
    {
        parent::boot($events);

        //
    }
}

你会把它登记在你的app.php.

然后我用每个事件的方法实现JWTEvents类。

class JWTEvents extends Event {
    
    // Other methods        

    public function invalid()
    {
        return response()->json(['error' => 'Token Invalid'], 401);
        die();
    }
}

需要注意的重要一点是,我们正在捕获JWT异常并返回带有特定状态代码的json响应。

在角度方面,我的httpInterceptor类中有这些http状态代码的捕获。

angular.module('ngApp')
    .factory('httpInterceptor', function($q, $log, $cookieStore, $rootScope, Response) {
        return {
            
            request: function(config) {
                // Where you add the token to each request
            },
            
            responseError: function(response) {

                // Check if response code is 401 (or whatever)
                if (response.status === 401) {
                    // Do something to log user out & redirect.
                    $rootScope.$broadcast('invalid.token');
                }
            }
        }
    });
 类似资料:
  • 问题内容: 注销HTTP身份验证受保护的文件夹的 正确 方法是什么? 有一些解决方法可以实现这一目标,但是它们可能会带来危险,因为它们可能有故障或在某些情况下/浏览器中无法使用。这就是为什么我要寻找正确和清洁的解决方案。 问题答案: 亩。 没有正确的方法 ,甚至没有跨浏览器一致的方法。 这是来自HTTP规范(第15.6节)的问题: 现有的HTTP客户端和用户代理通常会无限期地保留身份验证信息。HT

  • 问题内容: 我已经尝试过搜索,但是找不到我的问题的答案。 我正在从github玩这个应用程序:https : //github.com/Yalantis/Koloda/tree/master/Example 我之所以使用它,是因为我正在做一个项目,该项目将使用此应用程序中基于图块的滑动。 我也在使用Firebase。到目前为止,我可以将用户添加到数据库中,因此应用程序和firebase已连接。 我

  • 我一直在寻找使用各种AWS服务来处理我们下一个主要项目的基础设施。我们开始研究EC2实例上的docker容器,但在进一步研究AWS Lambda之后,这似乎是一条值得探索的道路。 使用AWS Lambda范例,我们只需使用Lambda函数作为逻辑粘合剂,将数据和事件(来自其他AWS服务)保存在一起。 例如,如果我们产品的用户创建了一个新记录,AWS Lambda可以在该事件中触发,我们可以调用La

  • 我正在跟踪这个问题的答案。 但我得到了这个错误: noSuchMethodError:没有虚拟方法removeAccount(Landroid/Accounts/Account;Landroid/App/Activity;Landroid/Accounts/AccountManagerCallback;Landroid/OS/Handler;)Landroid/Accounts/AccountMa

  • 我是Apache Shiro的初学者。我一直在跟踪文档和许多其他教程,博客等,但我就是无法使身份验证工作。当我尝试使用有效的用户名和密码登录时,总是会引发。我正在使用DynamoDB作为存储用户凭据的自定义领域,但我真的不认为这有什么关系。显然,我存储和/或执行凭据匹配的方式是不正确的。以下是我的设置:

  • 我试图在一个反应式Spring Boot应用程序中配置一个Spring Security性,该应用程序具有一个Vuejs前端,在未经身份验证时将用户重定向到外部OpenID提供程序(用于身份验证)。在用户通过OpenID提供程序进行身份验证并重定向回应用程序(前端)后,将根据OpenID提供程序的响应创建用户名密码身份验证令牌(身份验证),并手动进行身份验证。 但是,在执行此操作时,应用程序似乎无