Route::group(['middleware' => ['can:isManager', 'can:isOwner']], function() {
Route::get('accounts-overview',[\App\Http\Controllers\AccountsOwnerController::class, 'index'])->name('accounts-overview');
Route::get('accounts-settings',[\App\Http\Controllers\AccountsOwnerController::class, 'edit'])->name('accounts-settings');
Route::put('update-settings', [\App\Http\Controllers\AccountsOwnerController::class, 'update'])->name('update-settings');
Route::get('contract-overview', [\App\Http\Controllers\AccountsOwnerController::class, 'contractOverview'])->name('contract-overview');
});
How to assign multiple roles for the same routes
Related
My question can we use something like this in laravel routing like one routes for admin.domain.com and other routes for clients.domain.com. How achieve this in laravel routing.
For example:
// these needs to go clients.domain.com/route
Route::get('/clients', 'App\Http\Controllers\HomeController#index')->name('clients');
Route::get('/clients/order', 'App\Http\Controllers\KuponaiController#pridetiKupona')->name('clients.order');
//this one to admin.domain.com/admin
Route::get('/admin', 'App\Http\Controllers\KuponaiController#patvirtinimokodas')->name('dashboard');
There is clear documentation on how you can use subdomains in your Laravel application here https://laravel.com/docs/8.x/routing#route-group-subdomain-routing.
Route::domain('{account}.myapp.com')->group(function () {
Route::get('user/{id}', function ($account, $id) {
//
});
});
For this to work, you need to have this subdomain before registering root domain routes
Create a route group and pass an array with a domain property:
Route::group(['domain' => 'clients.domain.com'], function()
{
// clients.domain.com/clients
Route::get('/clients', 'App\Http\Controllers\HomeController#index')->name('clients');
// clients.domain.com/clients/order
Route::get('/clients/order', 'App\Http\Controllers\KuponaiController#pridetiKupona')->name('clients.order');
});
Route::group(['domain' => 'admin.domain.com'], function()
{
// admin.domain.com/admin
Route::get('/admin', 'App\Http\Controllers\KuponaiController#patvirtinimokodas')->name('dashboard');
});
In Laravel it is possible to target specific domains in routes like so:
Route::domain('example1.com')->group(...);
But how can I create a route that targets multiple domains like so:
Route::domain(['example1.com', 'example2.com'])->group(...);
You can use Pattern for this
Route::pattern('subdomain', '(dev.app|app)');
Route::group(['domain' => '{subdomain}.example.com'], function () {
...
});
--
Route::pattern('subdomain', '(dev.app|app)');
Route::pattern('domain', '(example.com|example.dev)');
Route::group(['domain' => '{subdomain}.{domain}'], function () {
...
});
I have the following code in my routes/web.php
Route::namespace('Admin')->middleware(['admin'])->group(function() {
Route::get('/posts', 'PostController#index');
});
Route::namespace('User')->middleware(['user'])->group(function() {
Route::get('/posts', 'PostController#index');
});
I wish to use the same uri "/posts" in both cases and keep the role logic (admin, user) out of the controllers, however, in this case, when I request the route "/posts" in always responds with the last one.
I can't seem to find information of what I am missing here.
use prefix for different route for admin and user
/admin/posts
Route::group(['namespace' => 'Admin','middleware=>'admin','prefix' => 'admin'],function() {
Route::get('/posts', 'PostController#index');
});
/user/posts
Route::group(['namespace' => 'User','middleware=>'user','prefix' => 'user'],function() {
Route::get('/posts', 'PostController#index');
});
You may try this one
Route::group(['prefix'=>'admin','middleware'=>'admin'],function (){
Route::get('/posts',['uses'=>' PostController#posts','as'=>'posts.index']);
});
Route::group(['prefix'=>'user','middleware'=>'user'],function (){
Route::get('/index',['uses'=>' PostController#posts','as'=>'posts.index']);
});
My ultimate objective is to limit accesses to the group of routes by validating permissions provided to the user.
These target 'group of routes' have ONE COMMON PARENT GROUP and may have zero or more sub-groups, such that, if access to these target 'group of routes' is permitted/accessible to the user then, all its sub-route groups are also accessible to the user.
To achieve this, I believe I need to differentiate these target group of routes by any uniqueString/parameter in middleware, which is indeed answered here.
But, I want to generalize this further, by applying middleware to common SINGLE PARENT GROUP of all these target group of routes and identify these target group of routes by any means in the middleware.
So, my question is how do I identify/differentiate these target group of routes in the middleware? Is there any way to do so?
Sample Code of what I am trying to describe:
Route::group(['prefix' => 'singleParent','middleware' => 'permissionMiddleware'], function (){
Route::group(['prefix' => 'target-group-1', 'groupUniqueString' => 'tsg1'], function (){
Route::group(['prefix' => 'sub-group-1.1'], function (){
});
Route::group(['prefix' => 'sub-group-1.2'], function (){
});
});
Route::group(['prefix' => 'target-group-2', 'groupUniqueString' => 'tsg2'], function (){
Route::get('route-1','Controller#method-of-Route1');
});
});
So, to specify a route group in your middleware to handle some actions, you can do it in this way :
Route::group(['prefix' => 'singleParent','middleware' => 'permissionMiddleware'], function (){
Route::group(['prefix' => 'target-group-1', 'as' => 'tsg1.'], function (){
//...
});
});
This will generate route names with the prefix : tsg1
Now in your middleware you can do like this to get the route group :
function getCurrentRouteGroup() {
$routeName = Illuminate\Support\Facades\Route::current()->getName();
return explode('.',$routeName)[0];
}
Updated
and to check :
if ($request->route()->named('name')) {
//
}
return $next($request);
Or in another approach you can achieve :
To get the prefix of a route group you can do something like this :
$uri = $request->path();
// this will give you the url path like -> if this is the url :
// http://localhost:8000/foo/bar you will get foo/bar
And then :
$prefix = explode('/',$uri)[0];
// and you will get 'foo'
Let me know if this works for you.
In web.php I have two middleware groups for two user roles - admins and non_admins:
Route::group(['middleware' => ['auth', 'admin']], function () {
// if user is logged in AND has a role of admin...
Route::get('/', 'Admin\IndexController#index');
});
Route::group(['middleware' => ['auth', 'non_admin']], function () {
// if user is logged in AND has a role of non_admin
Route::get('/', 'NonAdmin\IndexController#index');
});
Both admin and non_admin middleware check that the role of Auth::user() is admin or non_admin respectively; if it's not, the middleware fails with abort(403). Why do I not have a single middleware? The point of this to separate the two roles, so that each has its own independent controller logic and its own views.
Problem
If I log in as an admin I get 403, if I log in as a non_admin, it works as expected. My guess: Laravel sees the two duplicate routes, and only resolves the one that is defined last (which happens to be in ['middleware' => ['auth', 'non_admin']]).
Question
How do I resolve duplicate routes but separate controller and presentation logic? Again, admin and non_admin users will visit the same route ('/') but see two different views. I also want to implement this in two different controllers.
Hmmm....
I would personally keep everything encapsulated under a common controller, and perform the necessary checks and modifications using a service class.
But if you really want to keep everything separated under two different controllers based on your roles, you could do it this way. This assumes that you're using Laravel's built-in Authorization:
routes
Route::group(['middleware' => ['auth']], function () {
Route::get('/', function(){
$isAdmin = Auth::user()->can('do-arbitrary-admin-task');
$ns = $isAdmin ? 'Admin' : 'NonAdmin';
$controller = app()->make("{$ns}\\IndexController");
return $controller->callAction('index', $parameters = []);
});
});