I'm using building an SPA using Laravel and Vue and I don't want users to access the /products/create route I've tried using Laravel middlewares but it didn't help
Here's my App.vue component
<template>
<div>
<Navbar :name="user.name"/>
<router-view></router-view>
</div>
</template>
<script>
import Navbar from "./Navbar";
export default {
name: "App",
props: [
'user'
],
components: {
Navbar,
},
created() {
window.axios.interceptors.request.use(config => {
config.headers.common['Authorization'] = 'Bearer ' + this.user.api_token;
return config;
});
},
}
</script>
IsAdmin.php
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class IsAdmin
{
public function handle($request, Closure $next)
{
if (! Auth::user()->isAdmin) {
return response()->json(['error' => 'Unauthorized'], 403);
}
return $next($request);
}
}
How do I redirect non-authorized users to a 404 page?
To protect vue routes you can use navigation guards which are a specific feature within Vue Router that provide additional functionality pertaining to how routes get resolved.
You must be using vue-router package to use routes in vuejs app
In src/router/index.js , you can add route guard as following
import Vue from "vue";
import Router from "vue-router";
import Main from "@/components/Main";
import Products from "@/components/Products";
import Create from "@/components/Create";
import Show from "@/components/Show";
import Unauthorised from "@/components/Unauthorised";
//use vue router
Vue.use(Router);
//init Router and define some routes
export default new Router({
routes: [
{
path: '/',
name: 'Main',
component: Main
},
{
path: '/products',
name: 'Products',
component: Products
},
{
path: '/create',
name: 'Create',
component: Create
},
{
path: '/show',
name: 'Show',
component: Show
},
{
path: '/unauthorised',
name: 'Unauthorised',
component: Unauthorised
}
]
})
//apply route guard
router.beforeEach((to, from, next) => {
//list of blocked routes
const protectedRoutes = ['/products', '/create'];
//the route user is trying to access is in blocked routes list
if (protectedRoutes.includes(to.path)) {
//redirect to route having unauhorised message page
return next('/unauthorised');
}
)
else
{
// otherwise allow user to access route
return next();
}
In this example there are five routes i.e / , /products , /create , /show and last one /unauthorised to show error. Here, if any user tries to access routes listed in $protectedRoutes then they will be redirected to /unauthorised route otherwise allowed to access other routes
you can learn more about vue router guard here and about vue-router here.Additionally, you can guard your routes based on user roles or any other conditions.I recommend you to use vuex to manage user state and manage routes access based on role stored on user state
You're not providing enough information, but the way I do it is using Laravel policies.
I would setup a policy for Products like this:
namespace App\Policies;
use App\Product;
use App\User;
use Illuminate\Auth\Access\HandlesAuthorization;
class ProductPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can create products.
*
* @param \App\User $user
* @return mixed
*/
public function create(User $user)
{
return $user->hasPermissionTo('create products');
}
}
Register your policies in the App\Providers\AuthServiceProvider.php
protected $policies = [
'App\Product' => 'App\Policies\ProductPolicy',
];
Then in your Product controller you will need to add this in order to got through the authorization process:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Product;
class ProductController extends Controller
{
public function store(Request $request)
{
$this->authorize('create', Product::class)
// The current user is authorized to make this request.
}
}
You will probably like to prevent unauthorized users to even have access your vue route where you create products. In order to do so you would have to pass the users permissions into your vue app.
return [
'name' => $user->name,
'permissions' => [
'createProducts' => $user->can('create', \App\Product::class)
]
}
Then in your vue app:
<router-link v-if="user.permissions.createProducts" to="/products/create">
New Product
</router-link>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With