Laravel JWT多页结构

Jar*_*cia 6 php authentication jwt laravel vue.js

据我所知,基于JWT的授权系统通常保留给SPA'(你知道,一个视图,一个React/Angular/Vue应用程序,一个膨胀的app.js文件),但是我试图利用JWT的魔力使用稍微独立的结构化应用程序

结构体

blade.php我没有从我的Laravel应用程序中提供一个获取一个Vue应用程序和实例的视图,而是尝试提供两个独立的blade.php视图,每个视图都作为自己的独立视图运行Vue SPA:一个用于应用程序的外部(pre-auth),另一个用于应用程序的内部(授权后).

目前的应用状态

为了启动我应用程序的身份验证系统,我使用了Tymon的jwt-auth lib(一个漂亮的lib btw)并将所有内容绑在一起(如前所述)Vue/Vuex.一切都按预期工作,在我RegisterLogin组件中我能够点击我的api,得到JWT作为响应,在本地存储然后将所述令牌附加到我的Axios标题中,允许所有后续请求包含此标记.

困境

现在我正处于十字路口.我想要提供的post-auth路由/视图受自定义JWT中间件的保护,如果没有显示有效令牌,该中间件会重定向:

Route::get('/home', 'Auth\HomeController@home')->middleware('jwt');
Run Code Online (Sandbox Code Playgroud)

中间件

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的pre-auth视图及其所有路由都受到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);
    }
}
Run Code Online (Sandbox Code Playgroud)

问题

所以这归结为以下问题:

1)在前端成功注册/登录并生成JWT,存储在本地和Axios标题中之后,如何使用此有效令牌重定向到我的授权后路由?

2)如何确保有效JWT持续存在并且在访客路由被成功重定向回到我的授权后路由时存在?

如果可行,我宁愿在后端保留所有重定向和持久性检查

Jar*_*cia 0

所以这是我最终实现的逻辑:

在我的LoginController.php登录函数中,成功进行身份验证并生成 JWT 后,我返回带有 Json 和新 cookie 的响应,两者都传递了新的token内容:

public function login(Request $request)
{
    $creds = $request->only(['email', 'password']);

    if (!$token = auth()->attempt($creds)) {
        return response()->json([
            'errors' => [
                'root' => 'Incorrect Credentials. Try again'
            ]
        ], 401);
    }

    return $this->respondWithToken($token);
}

protected function respondWithToken($token)
{
    return response()->json([
        'meta' => [
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth()->factory()->getTTL() * 60
        ]
    ], 200)
    ->withCookie(cookie('access_token', $token, auth()->factory()->getTTL()));
}
Run Code Online (Sandbox Code Playgroud)

在我的来宾RedirectIfAuthenticated中间件中检查 cookie(如果存在),setToken然后将 Guard 设置为“Authenticated”(已验证),并且将始终重定向到/home令牌是否可用且有效:

public function handle($request, Closure $next, $guard = null)
{
    if ($request->hasCookie('access_token')) {
        Auth::setToken($request->cookie('access_token'));
    }

    if (Auth::guard($guard)->check()) {
        return redirect('/home');
    }

    return $next($request);
}
Run Code Online (Sandbox Code Playgroud)

在我的post-auth路由中间件中setToken,如果它有效并且存在,我也会允许访问,否则会抛出一系列JWT错误,这些错误只会重定向到预身份验证视图:

public function handle($request, Closure $next)
{
    JWTAuth::setToken($request->cookie('access_token'))->authenticate();

    return $next($request);
}
Run Code Online (Sandbox Code Playgroud)

最后,我决定在前端处理重定向,因为我使用的是 Axios,它是基于承诺的,可以确保在重定向到授权后视图之前设置 cookie,这样就不会发生有趣的事情了!干杯! 希望这对任何寻求多页 SPA 魔法的人有所帮助!