boisterouslobster
boisterouslobster

Reputation: 1293

SPA, Middleware, and VueRouter

I am working on a project that utilizes Vue2, VueRouter, and Laravel 5.4. It is a single page application. Laravel Passport for API authentication (AXIOS calls from my Vue components).

The majority of the app is served from one blade file (something like this):

<?php
//styling and the like
//...
//components being loaded here
<router-view></router-view>

//pull in the app.js file with vue router instantiation and routes
<script src="..."></script>

All components and routes are defined in an app.js file, that is pulled in this file.

The components being served through this blade file all require authentication; the user has to be signed in and registered.

However, the application will have one page which will be accessible to non-registered users. Anyone with the URL can access the page; however, before given access to the page, they will need to enter a security passcode.

The page will essentially be a form that the user will fill out and submit. It will also pull some data from the database beforehand, to populate some details on the page.

I have not set out to do anything of this nature and had trouble finding examples on how to do so. Though I have some ideas on how to go about it, this is my best guess:

  1. Create a new JS file that will host a new router.
  2. Create a new blade file that will host the router-view element. It will pull in the newly created JS file.
  3. Add route for the newly created blade file to the web.php file; create middleware that will intercept any attempted access to the URL test/{id}. If the middleware check is successful, and the user enters in a valid passcode, the middleware will pass along the request to view the resource. Otherwise, a redirect with an error.

web.php file:

//Route for those people who are taking a test
Route::get('/test/{id}', 'TestController@serveTest');

//The authenticate view
Route::get('/authenticate/{id}', 'TestController@serveAuthenticate')
            ->name('authenticate')
            ->middleware('auth.test');

The test controller file:

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Test;

class TestController extends Controller
{
    public function serveTest(Request $request) {
        return View('layouts.test');
    }

    public function serveAuthenticate() {
        return View('authenticate');
    }
}

The middleware:

<?php

namespace App\Http\Middleware;

use Closure;
use App\Test;

class verifyTestAccess {
    public function handle($request, Closure $next) {   
        //Calculate some conditions here
        //...

        //Direct user to the authentication view if some condition is true
        if($hasPasscode) {
            return redirect()->route('authenticate', ['id' => $request->route('id')]);
        }

        //Let user access resource since it must not be password protected
        return $next($request);
    }
}

New blade file:

<?php
//Load the one component
<router-view></router-view>

//pull in the protectedPage.js file with vue router instantiation and routes
//this is a different file than in the first blade view
<script src="..."></script>

Is this a good way to do it? I imagine there are some problems with this approach, and that it is not optimal to create a vue-router for pulling in one component.

Upvotes: 1

Views: 1270

Answers (1)

Duy Anh
Duy Anh

Reputation: 770

Best practice is to separate front-end and back-end. Since you are using Laravel Passport, you would be using JWT to login the users from VueJS.

So Laravel essentially will act as API, which means it should not hold any state. Everything will be checked with the access_token (generated and provided by api to client)

Restricted pages:

  • Laravel will have a middlware to check if the user can retrieve the information (using token)
  • VueRouter will have a navigation guards to prevent users access restricted pages (can be by checking if token is present or by other attribute)

Upvotes: 1

Related Questions