laravel / angularjs JWT 令牌刷新

Posted

技术标签:

【中文标题】laravel / angularjs JWT 令牌刷新【英文标题】:laravel / angularjs JWT token refresh 【发布时间】:2015-05-19 20:46:20 【问题描述】:

我正在 Angular/laravel 应用程序中实现 JWT 身份验证,但我遇到了令牌刷新问题。

这里是相关代码:

php:“监听”tymon.jwt.expired 事件的 laravel-jwt 监听器:

    /**
     * Fired when the token has expired
     * @param \Exception $e
     * @return \Illuminate\Http\JsonResponse
     */
    public function expired($e)
    
        $token = \JWTAuth::parseToken();

        Config::package('tymon/jwt-auth', 'jwt');
        $ttl = Config::get('jwt::refresh_ttl');

        $iat = Carbon::createFromTimestamp($token->getPayload()->get('iat'));
        $now = Carbon::now();

        // if renew ttl is expired too, return 401, otherwise let
        // the application generate a new token to frontend
        if ($iat->diffInMinutes($now) >= $ttl) 
            unset($iat, $now, $ttl);
            return response_failure(
                Lang::get('errors.api.auth.expired'),
                Config::get('status.error.unauthorized')
            );
        

        unset($iat, $now, $ttl);
    

PHP:“后”过滤器:

/*
|--------------------------------------------------------------------------
| JWT-Auth token-refresh Filter
|--------------------------------------------------------------------------
|
| The RefreshToken filter update the response headers by returning an 
| updated authentication token.
|
*/
Route::filter('RefreshToken', function($route, $request, $response)

    $token = JWTAuth::parseToken();

    try 
        $token->toUser();
     catch (TokenExpiredException $e) 
        Config::package('tymon/jwt-auth', 'jwt');
        $ttl = Config::get('jwt::refresh_ttl');

        $iat = \Carbon\Carbon::createFromTimestamp($token->getPayload()->get('iat'));
        $now = \Carbon\Carbon::now();

        if ($iat->diffInMinutes($now) < $ttl) 
            $response->headers->set('Authorization', 'Bearer ' . $token->refresh());
        
    
);

PHP:经过身份验证的路由过滤器:

Route::group(['before' => 'jwt-auth', 'after' => 'RefreshToken'], function ()  ... );

JS:更新本地存储的拦截器

'use strict';

angular.module('App')

    .factory('ResponseInterceptor', ['SessionService', 'jwtHelper', '$location', '$q',
        function (SessionService, jwtHelper, $location, $q) 

            return 
                response: response
            ;

            // called for http codes up to 300
            function response(response) 
                var token = response.headers('Authorization');
                if ('undefined' !== typeof token && null !== token) 
                    SessionService.setToken(token.split(' ')[1]);
                
                return response;
            
        ]);

除了一个问题(工作流程)之外,这很好用:

令牌已过期,但仍可续订 angular 向服务器发送带有过期令牌的 http 请求 laravel 捕获请求并使用新令牌更新响应标头 laravel 将前一个令牌列入黑名单

问题是,如果在 “更新” 延迟期间从 Angular 发送任何请求,所有这些请求都会被服务器拒绝,因为令牌无效(列入黑名单)。

我做错了吗?有人能指出我正确的方向吗?

我想要实现的是将令牌的 ttl 设置为大约 5 分钟,并允许用户在导航时更新令牌。

【问题讨论】:

在 Laravel 5.0 中同样的问题。 这个问题你解决了吗?我也对这个解决方案很感兴趣 嘿,这似乎是一个已知问题,检查这里,应该可以修复:github.com/tymondesigns/jwt-auth/issues/… 【参考方案1】:

也许您正在使用异步请求?然后,您不确定是否发送了最新的令牌。

在这种情况下,您不应该在每次请求后都使用刷新方法。

【讨论】:

问题是我评论的问题,我会给出答案以便其他人可以轻松找到它【参考方案2】:

这确实是库的一个错误,现已更正,read here 了解更多信息

【讨论】:

【参考方案3】:

我有同样的问题。刷新令牌时,最后一个令牌将被列入黑名单。 但是,如果在上次响应之前启动了另一个异步调用,则您需要此令牌。因此,解决方案可以延迟将最后一个令牌列入黑名单。你可以通过在jwt.php 配置文件中设置JWT_BLACKLIST_GRACE_PERIOD 来做到这一点。 ♥♥♥

【讨论】:

以上是关于laravel / angularjs JWT 令牌刷新的主要内容,如果未能解决你的问题,请参考以下文章

使用 Laravel、JWT 和 Angularjs 批处理令牌

使用 laravel 保护 javascript 资源

在没有会话的情况下使用 laravel socialite 和 jwt-auth

JWT 可以跨不同的 AngularJS 应用程序使用吗?

AngularJS 使用 JWT Auth 记住我的功能

Laravel,AngularJS和SEO