The page isn’t redirecting properly Laravel - laravel

I've been trying to make a conditional based on authentication, even though, my browser tells me this: The page isn’t redirecting properly which lets me know something of course is wrong.
Here are my routes:
$router->group(['middleware' => 'auth'], function() { // If the user is logged in
Route::get('/', 'IndexController#dashboard');
});
$router->group(['middleware' => 'guest'], function() { // If the user is not logged in
Route::get('/', 'IndexController#index');
});

Related

Resolve duplicate routes based on middleware group

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 = []);
});
});

Laravel: always adding user/{id} to routes or different method

I have a Laravel application. In the routes file, I have
Route::group(['prefix' => 'user'], function () {
Route::group(['middleware' => ['auth', 'roles'], 'roles' => ['buyer']], function() {
Route::get('dashboard/buyer', ['as' => 'buyer_dashboard', 'uses' => 'User\Buyer\DashboardController#index']);
});
Route::group(['middleware' => ['auth', 'roles'], 'roles' => ['seller']], function() {
Route::get('dashboard/seller', ['as' => 'seller_dashboard', 'uses' => 'User\Seller\DashboardController#index']);
});
});
I have a middleware that basically checks if the id as supplied in the route, is the same as the current logged in user. If this is not the case, I return an error page. The reason for having this is that I want to prevent that a user can access the dashboard of another user. I also want to prevent that a user can place a bid for someone else (by changing the id in the http request)
The issue is that in the first route, the id is referring to the user. In the second route, the id is referring to the lot id.
Am I obliged to change the second route to:
Route::get('{id}/lot/{lot}/bid/create', ['as' => 'buyer_lot_bid_create', 'uses' => 'User\Buyer\BidsController#create']);
where the first id refers to the user so that I can check the id of the user?
Or is there another way to prevent users from accessing other users pages without explicitly passing the user/{id} in the route?
Doing this in a middleware sounds like a bad idea. You've already come up against one exception to your middleware rule, and you'll certaily come across more.
There's two ways to do this:
Using laravel's built in authorisation tools: https://laravel.com/docs/5.1/authorization
If the check is that the "id as supplied in the route, is the same as the current logged in user" then there's no need to pass the user's id in via the route at all. The user can just visit eg. /dashboard/buyer with no params in the route. Who's dashboard are they visiting? The one of the logged in user, of course. So there's no way for a user to even try to visit another user's dashboard. Likewise with bidding. You can make your bid endpoint so that the bidder's id is not passed in via a route - it's just set to the id of the logged in user in your controller method. So again, there's no way to even try to bid on behalf of another user.
class AuthServiceProvider extends ServiceProvider
{
public function boot(GateContract $gate)
{
$this->registerPolicies($gate);
$gate->define('see-profile', function ($user, $profile) {
return $user->id === $profile->user_id;
});
}
Controller:
public function profile($id)
{
$post = Profile::findOrFail($id);
if (Gate::denies('see-profile', $profile)) {
abort(403);
}
}

Laravel and Sentinel: mix roles middleware for authorization

I'm a Laravel newbie (VERY newbie) using Cartalyst Sentinel on Laravel 5.2 to leverage roles authorizations.
On the admin section I have three (or more) roles, i.e. "admin", "agent" and "writer".
I also have some sections that should have mixed roles access, i.e. like this:
dashboard (accessible to all roles: admin, agent, writer)
users (accessible to: admin)
orders (accessible to: admin, agent)
pages (accessible to: admin, writer)
no_admin_here (accessible to: agent, writer)
At the moment I managed it to work with only two roles, but now I am stuck.
What I've done so far (I put only the necessary code):
routes.php
// only authenticated users can access these pages
Route::group(['prefix' => 'admin', 'as' => 'admin.', 'middleware' => ['check']], function(){
// these pages are accessible to all roles
Route::get('dashboard', ['as' => 'dashboard', function(){
return view('admin/dashboard');
}]);
// only admin can access this section
Route::group(['middleware' => 'admin'], function(){
Route::get('users', function(){
return view('admin/users');
});
});
});
SentinelCheck Middleware (named 'check' in Kernel.php)
if (!Sentinel::check()) { // user is not authenticated
return redirect()->route('admin.login')->with('error', 'You must be logged to view the page');
}
if (Sentinel::inRole('customer')) { // user is authenticated but he is a customer
return redirect()->route('admin.login')->with('error', 'You are a customer and cannot access to backend section');
}
SentinelAdmin Middleware (named 'admin' in Kernel.php)
if (!Sentinel::inRole('admin')) { // user is authenticated but he is not an admin
return redirect()->route('admin.login')->with('error', 'You are not admin and cannot view requested section');
}
SentinelAgent Middleware (named 'agent' in Kernel.php)
if (!Sentinel::inRole('agent')) { // user is authenticated but he is not an agent
return redirect()->route('admin.login')->with('error', 'You are not agent and cannot view requested section');
}
So far so good, as I said, but things mess up when I try to mix roles; i.e. I can't write a route like this:
// only admin and agent can access this section
Route::group(['middleware' => ['admin', 'agent']], function(){
Route::get('orders', function(){
return view('admin/orders');
});
});
because "agent" will never reach the section since "admin" middleware will block and logout him. And, likewise, I can't do every other roles mix:
['middleware' => ['admin', 'writer']]
['middleware' => ['agent', 'writer']]
['middleware' => ['admin', 'writer', 'whatever_else_role']]
etc..
So, is there a (easy) way in which I can easily mix roles accesses to sections? Thanks in advance for your help
It was easier that I expected using middleware parameters

How to use any one of multiple filters in route in Laravel 4.2

I am developing my application in Laravel 4.2. I have 2 filters in my application named guest and admin. Admin can access to all controllers and guest can access to only few controllers.
This is the route for admin
Route::group(array('before' => 'admin'), function()
{
\\controller functions
});
But I want to route functions for guest. I tried in this way
Route::group(array('before' => 'admin'|'guest'), function()
{
\\some controller functions
});
But this type routing checks for both filters... But I need to check the user is Admin or Guest How will i configure the route? Can anyone help??
Make third filter, that will check if user is guest or admin, for example the name is guestOrAdmin.
Than write a code like this:
Route::group(array('before' => 'guestOrAdmin'), function()
{
\\all your controller functions which can be accessed by guests and admins
Route::group(array('before' => 'guest'), function()
{
\\some controller functions which can be access only by guest
});
Route::group(array('before' => 'admin'), function()
{
\\some controller functions which can be access only by admin
});
});

How to add filter laravel

How add filter, when I logged in, and I enter user/login or user/register on url, I want to redirect to home.
and when I logged out, and I want to protect user/panel
Laravel has filters options the official website states the following for the filters
Route filters provide a convenient way of limiting access to a given route, which is useful for creating areas of your site which require authentication. There are several filters included in the Laravel framework, including an auth filter, an auth.basic filter, a guest filter, and a csrf filter. These are located in the app/filters.php file.
Defining a route filter
Route::filter('old', function()
{
if (Input::get('age') < 200)
{
return Redirect::to('home');
}
});
If the filter returns a response, that response is considered the
response to the request and the route will not execute. Any after
filters on the route are also cancelled.
Attaching a filter to the route
Route::get('user', array('before' => 'old', function()
{
return 'You are over 200 years old!';
}));
You can find complete documentation here
Route.php
Route::group(array('prefix'=>'user','before' => 'isUser'), function () {
Route::get('register', array('as' => 'register', 'uses' => 'UsersController#create'));
Route::get('login', array('as' => 'login', 'uses' => 'UsersController#login'));
// add post routes as required
});
filters.php
Route::filter('isUser', function ()
{
// I have used Sentry for user Authorisation
if (Sentry::check()) {
return Redirect::to('/')->with('message', "You are already logged in.");
}
else{
// benefit of using Redirect::guest() is that you can use Redirect::intended()
return Redirect::guest('login');
}
});

Resources