无痛刷新jwt-token多[guard]版本

<?php

namespace App\Http\Middleware;

use Auth;
use Closure;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Http\Middleware\BaseMiddleware;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;

class RefreshToken extends BaseMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     *
     * @throws \Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException
     *
     * @return mixed
     */
    public function handle($request, Closure $next, $role='api')
    {
        // 检查此次请求中是否带有 token,如果没有则抛出异常。 
        $this->checkForToken($request);

        // 判断token是否在有效期内
        try {
            if (auth($role)->payload())  {
                 app('auth')->shouldUse($role);
                return $next($request);
            }
        } catch (JWTException $exception) {
            try{
                $token = auth($role)->refresh();
                // 使用一次性登录以保证此次请求的成功
                auth($role)->onceUsingId(
                    auth($role)->payload()->get('sub')
                );
                //更新请求中的token
                $request->headers->set('Authorization','Bearer '.$token);
            } catch(JWTException $exception) {
                // 如果捕获到此异常,即代表 refresh 也过期了,用户无法刷新令牌,需要重新登录。
                throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage());
            }
        }
        // 在响应头中返回新的 token
        $token = $token ?: auth($role)->refresh();
        $response = $next($request);
        $response->headers->set('Authorization', 'Bearer '.$token);
        return $response;
    }
}

使用方式:route中间件中添加
'refresh.token:role'
特别注意:
1、当使用refresh.token:role中间件之后遇到用户授权authorize失败。导致非默认guard的角色操作授权失败。
因为app.auth即AuthManager里面使用的guard是auth中配置的默认guard。

AuthServiceProvider.php:

protected function registerAuthenticator()
    {
        $this->app->singleton('auth', function ($app) {
            $app['auth.loaded'] = true;
            return new AuthManager($app);
        });

        $this->app->singleton('auth.driver', function ($app) {
            return $app['auth']->guard();
        });
    }

AuthManager.php:

 /**
     * Get the default authentication driver name.
     *
     * @return string
     */
    public function getDefaultDriver()
    {
        return $this->app['config']['auth.defaults.guard'];
    }

这将导致我们的policy授权方法无法注入正确的user导致授权失败。
所以在RrefreshToken中间件中获取到正确的token时候,我们需要修改AuthManager的guard。避免用户操作无法正确授权。

无痛刷新jwt-token多[guard]版本

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 3年前 自动加精
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 2

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!