版本
- "tymon/jwt-auth": "1.0.0-rc.1"
- "laravel/framework": "5.5.*"
tymon/jwt 的使用
这里省略安装步骤,直接写使用过程
- auth.php
'api' => ['driver' => 'jwt','provider' => 'users',
],
- 路由调用
Route::middleware(['auth:api'])->group(function(){
});
Auth 中间件是如何调用 Guard
在请求通过路由时执行中间件,auth 中间件实例化的是 Illuminate\Auth\Middleware\Authenticate 类:
<?phpnamespace Illuminate\Auth\Middleware;use Closure;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Contracts\Auth\Factory as Auth;class Authenticate
{/*** The authentication factory instance.** @var \Illuminate\Contracts\Auth\Factory*/protected $auth;/*** Create a new middleware instance.** @param  \Illuminate\Contracts\Auth\Factory  $auth* @return void*/public function __construct(Auth $auth){$this->auth = $auth;}/*** Handle an incoming request.** @param  \Illuminate\Http\Request  $request* @param  \Closure  $next* @param  string[]  ...$guards* @return mixed** @throws \Illuminate\Auth\AuthenticationException*/public function handle($request, Closure $next, ...$guards){$this->authenticate($guards);return $next($request);}/*** Determine if the user is logged in to any of the given guards.** @param  array  $guards* @return void** @throws \Illuminate\Auth\AuthenticationException*/protected function authenticate(array $guards){if (empty($guards)) {return $this->auth->authenticate();}foreach ($guards as $guard) {if ($this->auth->guard($guard)->check()) {return $this->auth->shouldUse($guard);}}throw new AuthenticationException('Unauthenticated.', $guards);}
}
请求过来后使用了中间件,会调用 handle 方法
 所以我们看到 authenticate 方法中,会循环调用 guard 的 check 方法,成功会返回 auth 实例,失败则统一抛出 AuthenticationException
namespace Illuminate\Auth;use Exception;class AuthenticationException extends Exception
{/*** All of the guards that were checked.** @var array*/protected $guards;/*** Create a new authentication exception.** @param  string  $message* @param  array  $guards* @return void*/public function __construct($message = 'Unauthenticated.', array $guards = []){parent::__construct($message);$this->guards = $guards;}/*** Get the guards that were checked.** @return array*/public function guards(){return $this->guards;}
}
可以在 App\Exceptions\Handler 中的 unauthenticated() 捕获该异常,这也是为什么不管是 token 过期还是拉黑,使用 auth 中间件的错误提示一直是 Unauthenticated. 的原因!
为什么使用 auth:jwtGuard 的方式
因为 jwt.auth 不能指定 guard ,只会调用默认的 guard ,当你的 default 指向 web 时,会导致一直未认证。
 解决办法:
- 定义中间件,每次调用 jwt.auth前,都把默认的guard指定为你当前路由适用的guard
- 使用 auth:jwtGuard的调用方式,如auth:api,api的guard driver选择jwt,这样在错误信息返回时就没有具体原因了,都是统一的Unauthenticated.