简介配置 Laravel 5.6 + JWT + AngularJS 配置 Api 跨域授权访问,以及实现 Token 刷新。 因内容较多,涉及较广,这里只能概括的讲一下了。
详细配置过程,请查看官方文档。
composer require tymon/jwt-auth "1.0.0-rc.2"
php artisan jwt:secret
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
app/Http/Kernel.php
protected $routeMiddleware = [
...
'refresh.token' => \App\Http\Middleware\RefreshToken::class
...
];
RefreshToken 中间件
class RefreshToken extends BaseMiddleware
{
public function handle($request, Closure $next)
{
// 检查此次请求中是否带有 token,如果没有则抛出异常。
$this->checkForToken($request);
Log::debug($request->headers->all());
// 使用 try 包裹,以捕捉 token 过期所抛出的 TokenExpiredException 异常
try {
// 检测用户的登录状态,如果正常则通过
if ($this->auth->parseToken()->authenticate()) {
return $next($request);
}
$token = $this->auth->refresh();
// 使用一次性登录以保证此次请求的成功
} catch (TokenExpiredException $exception) {
// 此处捕获到了 token 过期所抛出的 TokenExpiredException 异常,我们在这里需要做的是刷新该用户的 token 并将它添加到响应头中
try {
// 刷新用户的 token
$token = $this->auth->refresh();
// 使用一次性登录以保证此次请求的成功
Auth::guard('api')->onceUsingId($this->auth->manager()->getPayloadFactory()->buildClaimsCollection()->toPlainArray()['sub']);
} catch (JWTException $exception) {
// 如果捕获到此异常,即代表 refresh 也过期了,用户无法刷新令牌,需要重新登录。
throw new UnauthorizedHttpException('jwt-auth', $exception->getMessage());
}
}
// 在响应头中返回新的 token
return $this->setAuthenticationHeader($next($request), $token);
}
}
详细配置过程,请查看官方文档。
exposedHeaders
,不然无法跨域获取到 header 中的 Authorization 值来刷新前端令牌。 'exposedHeaders' => ['Authorization'],
class LoginController extends ApiController
{
use AuthenticatesUsers;
public function login(LoginRequest $request)
{
$credentials = $this->credentials($request);
if ($token = auth('api')->attempt($credentials)) {
$user = auth('api')->user();
return $this->success(
[
'user' => $user,
'token' => $token,
]);
}
return $this->failed('账号或密码错误!');
}
public function username()
{
return 'username';
}
}
Route::middleware('api')->prefix('api/user')->namespace('Modules\Account\Http\Controllers\Api')->group(function () {
Route::post('login', 'LoginController@login')->name('user.login');
});
public function __construct(UserRepository $repository)
{
$this->middleware('refresh.token')->only([
'getList', 'get', 'update'
]);
$this->repository = $repository;
}
在登录授权时,将返回的 token 存储在 TokenService 中进行管理。
this.tokenService.set({
token: res.data.token
});
拦截器将每一个请求的头中放入 Authorization 信息。
setReq(req: HttpRequest<any>, options: DelonAuthConfig): HttpRequest<any> {
return req.clone({
setHeaders: {
Authorization: `Bearer ${this.model.token}`,
},
});
}
如果返回的 Response 的 Header 中有 Authorization 信息,说明请求中带的 Token 已经过期,服务器将 刷新的 Token 放在了 Response 头中。前端获取后更新 Token 。
let newAuth = event.headers.get('Authorization');
if (newAuth) {
let token = newAuth.slice(7);
this.tokenService.set(Object.assign(this.tokenService.get(), {
token: token,
}));
}
本文为秋叶听风原创文章,转载无需和我联系,但请注明来自秋叶听风博客http://ice90.cn
最新评论