据我所知,基于 JWT 的授权系统通常是为 SPA 保留的(你知道,一个 View ,一个 React/Angular/Vue 应用程序,带有一个臃肿的 app.js 文件),但是我正在尝试利用JWT 的魔力与稍微独立的结构化应用程序。
结构
不是从我的 Laravel
应用程序提供一个 blade.php
View ,它获得一个 Vue
应用程序和实例,我试图提供两个单独的 blade.php
View ,每个 View 都作为自己单独的 Vue SPA
运行:一个用于应用程序的外部(预auth)和另一个用于应用程序内部(授权后)。
应用的当前状态
为了支持我的应用程序的身份验证系统,我使用了 Tymon's jwt-auth 库(顺便说一句,一个漂亮的库)并在前面用(如前所述)Vue/Vuex
将所有内容捆绑在一起。一切都按预期工作,在我的 Register
和 Login
组件中,我能够访问我的 api,获得 JWT 作为响应,将其存储在本地,然后将所述 token 附加到我的 Axios header 允许所有后续请求包含此 token 。
困境
现在我正处于十字路口。我想要提供的授权后路由/ View 受自定义 JWT
中间件保护,如果未提供有效 token ,该中间件会重定向:
Route::get('/home', 'Auth\HomeController@home')->middleware('jwt');
中间件
class JWT
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
JWTAuth::parseToken()->authenticate();
return $next($request);
}
}
我的预授权 View 及其所有路由都受到 Laravel 的本地访客 RedirectIfAuthenticated
中间件的保护,它现在由 JWT 保护:
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/home');
}
return $next($request);
}
}
问题
所以这可以归结为以下问题:
1) 在前端成功注册/登录并生成 JWT 并存储在本地和 Axios header 中之后,我如何使用此有效 token 重定向到我的授权后路由?
2) 然后我如何确保有效的 JWT 持续存在并在访问访客路由时出现以成功重定向回我的授权后路由?
如果可行,我宁愿在后端保留所有重定向和持久性检查
最佳答案
成功登录后,您将获得 token ,假设其名称为 $jwt_token
您可以在授权后重定向到您正在保护的页面,并在响应中设置 cookie:
return redirect('/home')->cookie(
'access_token', //name
$jwt_token, //value
config('session.lifetime'), //expiration in minutes (matches laravel)
config('app.url'), // your app url
true // HttpsOnly
);
从这里,Axios 可以通过解析文档上的 cookie 并检索 access_token
let token = document.cookie.split(';') // get all your cookies
.find(cookie => cookie.includes('access_token')) // take only the one that matches our access_token name
.split('=')[1] // get just the value after =
// terrible code example above for you
现在您可以在 Axios 请求中使用它,方法是将它作为值添加到 Authorization
header 中的 Bearer
:
Authorization: `Bearer ${token}`
您的 JWT
中间件已经利用了 authenticate
方法,因此它应该照原样为您处理 expiry
:
JWTAuth::parseToken()->authenticate();
在后台,这将尝试根据 config/jwt.php
文件中设置的当前 TTL 验证 token 的到期时间。考虑到您的工作流程,如果 token 过期,我也会将其列入黑名单
。您可以添加一个 Event Listener
来监听过期的 token 并通过监听 Event::listen('tymon.jwt.expired');
将它们列入黑名单。
请原谅任何语法错误、格式问题或拼写错误,我正在处理,稍后将进行编辑以解决这些问题。
关于php - Laravel JWT 多页面结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49432567/