php - Laravel JWT 多页面结构

标签 php laravel authentication vue.js jwt

据我所知,基于 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 将所有内容捆绑在一起。一切都按预期工作,在我的 RegisterLogin 组件中,我能够访问我的 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

来访问 cookie
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/

相关文章:

php - 如何使用 xenforo 选项获取要重新填充的复选框

php - 影响数据库的 Laravel 测试用例 - 使用最佳实践

java - 如何使用 Windows Java 客户端保存 Kerberos 服务票证?

mysql - 使用 laravel 查询生成器在另一个表中使用列值

php - 如何更改 token guard 中的 api_token 列

ruby-on-rails - Rails + Devise-自定义 Controller 中的Authenticate方法

php - codeigniter 在 url 中的方法之前传递参数?

php - mySQL自动增量问题: key 1的条目“4294967295”重复

php - codeigniter 4 设置 session 变量 $session =\Config\Services::session();全局

mysql - 在 Laravel 中需要关系数据