Laravel auth check for all pages - php

I have created the Authentication, and its working perfectly. But there is some problem in checking the inner pages. For example,
Route::get('/', array('before' => 'auth' , 'do'=> function(){
return View::make('home.index');
}));
The index page is only visible for logged in users. But whenever I have go to the inner pages, for example example.com/products. The products page can be visible without log in.

Here is my solution.
/**
* Groups of routes that needs authentication to access.
*/
Route::group(array('before' => 'auth'), function()
{
Route::get('user/logout', array(
'uses' => 'UserController#doLogout',
));
Route::get('/', function() {
return Redirect::to('dashboard');
});
Route::get('dashboard', array(
'uses' => 'DashboardController#showIndex',
));
// More Routes
});
// Here Routes that don't need Auth.

There are several ways of applying filters for many routes.
Putting rotues into Route::group() or if you using controllers add the filter there, add it in the Base_Controller so it will be applied to all. You can also use filter patterns and use a regex which applies the filter to all except a few you don't want to.
Documentation
Route filters: http://laravel.com/docs/routing#route-filters
Example to the pattern filter, as the others are basicly in the docs. This one could be the fastest but also the most problematic because of the problematic way of registering a regex in this function (the * is actually converted into (.*)).
Route::filter('pattern: ^(?!login)*', 'auth');
This will apply auth to any route except example.com/login.

Route::group(['middleware' => ['auth']], function()
{
Route::get('list', 'EventsController#index');
});
Read more on the documentation page:
https://laravel.com/docs/5.2/routing#route-groups

There may be a better way but I take a whitelist approach. Everything is blocked from public except for what the pages I put in this array.
// config/application.php
return array(
'safe' => array(
'/',
'card/form_confirm',
'record/form_create',
'card/form_viewer',
'user/login',
'user/quick_login',
'user/register',
'info/how_it_works',
'info/pricing',
'info/faq',
'info/our_story',
'invite/accept',
'user/terms',
'user/privacy',
'email/send_email_queue',
'user/manual_login',
'checkin/',
'checkin/activate',
'system/list',
),
// routes.php
Route::filter('before', function()
{
// Maintenance mode
if(0) return Response::error( '503' );
/*
Secures parts of the application
from public viewing.
*/
$location = URI::segment(1) . '/' . URI::segment(2);
if(Auth::guest() && !in_array( $location, Config::get('application.safe')))
return Redirect::to( 'user/login' );
});

this code working fine with me
Auth::routes();
Route::group(['middleware' => 'auth'], function () {
// Authentication Routes...
Route::get('/', 'HomeController#index')->name('home');
});

The same problem can be solved using a BaseController to extends all Controller have must logged user.
Example:
class SomeController extends BaseController
{
public function index() { return view('some.index');}
}
just add a __construct() method to BaseController
class BaseController extends Controller
{
protected $redirectTo = '/myIndex'; // Redirect after successfull login
public function __construct()
{
$this->middleware('auth'); // force all controllers extending this to pass auth
}
}
More info here

Just check if user is logged in in your views.
Or restrict all controller (if you use it)
Or check Route Groups, and give a filter to whole group of routes: http://laravel.com/docs/routing#groups

Route::filter('pattern: /*', array('name' => 'auth', function()
{
return View::make('home.index');
}));

It worked for me . take a look at it.
Route::when('*', 'auth.basic');
Route::get('api/getactorinfo/{actorname}', array('uses' =>'ActorController#getActorInfo'));
Route::get('api/getmovieinfo/{moviename}', array('uses' =>'MovieController#getMovieInfo'));
Route::put('api/addactor/{actorname}', array('uses' =>'ActorController#putActor'));
Route::put('api/addmovie/{moviename}/{movieyear}', array('uses' =>'MovieController#putMovie'));
Route::delete('api/deleteactor/{id}', array('uses' =>'ActorController#deleteActor'));
Route::delete('api/deletemovie/{id}', array('uses' =>'MovieController#deleteMovie'));

Related

Laravel routing without appending any prefix

I have a path in Laravel it is like subdomain.mydomain.com/admin/login
I am trying to call
subdomain.mydomain.com and need to get the login page straight.
Currently, it's not working
This is the function I am using in routerserviceprovider.php
protected function mapAdminRoutes()
{
Route::middleware('subdomain.mydomain.com')
->prefix('admin')
->namespace($this->namespace)
->group(base_path('routes/admin.php'));
}
and in admin.php there is a resource group shows like this:
Route::group(['prefix' => 'admin', 'namespace' => 'Admin'], function() {
//Login Routes...
Route::view('login','admin.login');
});
can anyone help with this?
Add following route
Route::get('/',function(){ return view('login.index'); })->name('admin.login');
i hope it helps

Laravel 5.3: localhost redirected you too many times

I have 2 user roles which is superadmin and admin
I don't want admin to access of Settings Page.
I am not sure if this is the proper way.
So, here's my SettingsController.php
class SettingsController extends Controller {
public function index() {
if(Auth::user()->roles == 0) {
return redirect(url()->previous());
} else {
return view('settings.index');
}
}
}
As you can see if the roles is 0. I redirect the user to the last page they're in. I also tried to use return back();
web.php (routes)
<?php
Route::get('/', ['uses' => 'UsersController#index']);
Route::post('login', ['uses' => 'UsersController#login']);
Route::group(['middleware' => ['auth']], function() {
Route::get('logout', ['uses' => 'UsersController#destroy']);
Route::get('upline', ['uses' => 'UplinesController#index']);
Route::get('upline/create', ['uses' => 'UplinesController#create']);
Route::post('upline', ['uses' => 'UplinesController#store']);
Route::delete('upline/destroy/{id}', ['uses' => 'UplinesController#destroy']);
Route::put('upline/update/{id}', ['uses' => 'UplinesController#update']);
Route::get('upline/getdownlines/{id}', ['uses' => 'UplinesController#getDownlines']);
Route::get('downline', ['uses' => 'DownlinesController#index']);
Route::post('downline', ['uses' => 'DownlinesController#store']);
Route::delete('upline/destroy/{id}', ['uses' => 'DownlinesController#destroy']);
Route::put('downline/update/{id}', ['uses' => 'DownlinesController#update']);
Route::get('bonus', ['uses' => 'BonusController#index']);
Route::post('bonus/csv', ['uses' => 'BonusController#fileUpload']);
Route::get('settings', ['uses' => 'SettingsController#index']);
});
I have a 2nd question. Can I limit admin using middleware? If yes, how?
Any help would be appreciated.
Maybe the second option, "Limiting admin with middleware".
So you can try something like;
Route::group(['prefix' => 'admin', 'middleware' => 'auth'], function () {
Route::get('/', 'DownlinesController#update');
});
Then
Route::group(['prefix' => 'super', 'middleware' => 'auth'], function () {
Route::get('/', 'UplinesController#index');
});
As #michael s answer suggests use middleware, his answer fails to demonstrate on how to do it (mine too, I just added more text).
Note: Laravel is big because of its documentation, USE IT!
You have 2 (or more options):
parameterized middleware
2 distinctive middlewares (one for admin, another for superadmin)
Note: use artisan to generate middleware from stubs, $ php artisan make:middleware MyNewShinyMiddleware
parametrized middleware (my pick)
Head to documentation and check out this.
Example shows exactly your problem.
public function handle($request, Closure $next, $role)
{
if (! $request->user()->hasRole($role)) { //implement hasRole in User Model
// Redirect...
// (use named routes to redirect or do 401 (unauthorized) because thats what is going on!
// abort(401) // create view in /views/errors/401.blade.php
// return redirect()->route('home');
}
//success user has role $role, do nothing here just go to another "onion" layer
return $next($request);
}
2 distinctive middlewares
simply create two middlewares and hardcode your checking routine of roles
(same as you do in your controller sample) except use $request->user()...
(routes) web.php
Route::group(['middleware' => 'role:admin'], function () {...} //parametrized
Route::group(['middleware' => 'checkRoleAdmin'], function () {...}
Route::group(['middleware' => 'checkRoleSuper'], function () {...}
Note: role, checkRoleAdmin and checkRoleSuper are "named" middlewares and you need to register them in kernel.php
Another way is yo use gates or policies which make the best sense, since you are trying to limit user. Read more here.
I use middleware based ACL for really simple projects (like one admin and no real users).
I use gates based ACL for medium projects (1-2 roles).
I use policies based ACL for "huge" projects (many roles, many users).
Also consider looking at https://github.com/Zizaco/entrust

Laravel redirect to route

I'm using Laravel 5.1 and wanted to know if there is a better way to do routing redirection.
Route::get('user/login', 'UserController#login');
Route::get('login', function() {
return redirect()->to('user/login');
});
So basically, whenever a user goes to http://example.com/login, they will be redirect to http://example.com/user/login.
Is there a better way or other ways to do this or am I doing it correctly already? Thanks!
That's about as simple as it gets
You could also do redirect('user/login') to save a few characters
If you had multiple redirects like this you could handle them all at once
Route::pattern('user_path', '(login|logout)');
Route::get('{user_path}', function($user_path) {
return redirect('user/' . $user_path);
});
Route::get('new/create_view','CreateController#create_view');
Route::post('new/create_view','CreateController#insert_view');
Route::get('new/create_table','CreateController#create_table');
Route::post('new/create_table','CreateController#insert_table');
Route::get('new/create_package','CreateController#create_package');
Route::post('new/create_package','CreateController#insert_package');
This is the way i am using the route. Simple method. when the time of GET, am calling a controller function and inside that particular controller function, i have written the logical codes. In the POST also, doing the same thing.
Another way is there,GROUP Routing
Route::group(['namespace' => 'Admin'], function()
{
// Controllers Within The "App\Http\Controllers\Admin" Namespace
Route::group(['namespace' => 'User'], function()
{
// Controllers Within The "App\Http\Controllers\Admin\User" Namespace
});
});
eg:
Route::group(array('prefix' => 'api/v1', 'before' => 'auth.basic'), function()
{
Route::resource('pages', 'PagesController', array('only' => array('index', 'store', 'show', 'update', 'destroy')));
Route::resource('users', 'UsersController');
});

laravel how to create page restriction

Please tell me how to restrict the page using laravel,
i have 3 users.
1. admin, 2. client, 3. partner
i want if admin is logged in then open only- admin.index page
and if client logged in then open only- client.index page
i used in route.php following code-
Route::group(array('before' => 'role'), function(){
Route::resource('admin','AdminController#index');
Route::resource('client','clientController#index');
Route::resource('partner','partnerController#index');
});
using above code this if no any user login then it's coming properly,
and suppose if admin logged in, then page redirect to AdminController but,
if i hard coded (url) hit clientController or partnerController like http://localhost/laravel-login/public/client then client page is coming.
so please tell me how to avoid these
sorry for my english..
thanks
You may use different route filters for each route and create individual filters, for example:
Route::group(array('before' => 'auth'), function() {
Route::resource('admin','AdminController#index');
Route::resource('client','clientController#index');
Route::resource('partner','partnerController#index');
});
In each controller create a __construct method and add filter like:
public function __construct()
{
// In your AdminController
$this->beforeFilter(function() {
if(Auth::user()->role->name != 'admin') return redirect::to('/'); // home
});
}
Same way declare other filters in other controllers:
public function __construct()
{
// In your clientController
$this->beforeFilter(function() {
if(Auth::user()->role->name != 'client') return redirect::to('/'); // home
});
}
And so on. Check more on Laravel website about controller filtering.
The best way to restrict controllers to make new middleware , where you can define rules before the request. example :
I have a admin controller only register users with admin role can access it .
to do so when you define the route include the middleware .
// namespace = indicate where my controller is (sub folder )
// middleware = indicate what restriction i want for my controller you can pass one middleware or array of midlewares
Route::group([ 'namespace' => 'Admin','middleware' => ['auth' , 'IsAdmin'] ], function()
{
Route::resource('admin/posts', 'PostsController');
});
to create the middle ware and register it follow the documentation
look this is my middleware after
<?php
namespace App\Http\Middleware;
use Closure;
class IsAdmin
{
public function handle($request, Closure $next)
{
if($request->user()->is_admin == false ){
return redirect('/');
}
return $next($request);
}
}

Best way to check permissions with sentry 2 at Laravel

Im developing a basic aplication core, first im working with user/groups and & permissions access.
I choose Sentry 2 to work, and i want to limit the access to my.domain/admin to a users or groups that have admin permissions.
Im developing a filter to check if the user is admin and if hasAccess to a specific action, like users.index, or users.custom_fuction.
In my routes i have:
/**
* ADMIN ROUTES
*/
Route::group(array('before' => 'sentry'), function() {
Route::group(array('before' => 'admin'), function() {
Route::group(array('prefix' => 'admin'), function()
{
Route::get('/', function()
{
return View::make('admin');
});
Route::resource('groups', 'GroupController',
array('except' => array('show')));
Route::resource('users', 'UserController',
array('except' => array('show')));
Route::get('users/{id}/groups', 'UserController#groups');
Route::post('users/{id}/groups', 'UserController#store_groups');
Route::get('{table}/{id}/permissions',
'PermissionController#manage_entity');
Route::post('{table}/{id}/permissions',
'PermissionController#update_permissions');
});
});
});
The sentry filter only checks if is loged and rediret to login page, the admin filter is:
/*
* Sentry admin & hasAccess filter
*/
Route::filter('admin', function()
{
$user = Sentry::getUser();
if (!$user->hasAccess('admin')) return Redirect::to('/');
// Ask if user hasAccess to specific action
var_dump(Route::getCurrentRoute()->getPath());
var_dump(Route::getCurrentRoute()->getAction());
});
I have to make another check with the actual route, in the getAction array there are a
'as' => string 'admin.users.index' (length=17)
I can use that for Route::resource i define but, how i did for other functions like groups or permissions.
Maybe there is a better way to handle that, but i dont know it.
Thanks in advice.
I found the solution:
http://laravel.com/docs/routing#named-routes
And now i have:
Route::get('users/{id}/groups', array('as' => 'admin.users.groups', 'uses' => 'UserController#groups'));
Route::post('users/{id}/groups', 'UserController#store_groups');
Route::get('{table}/{id}/permissions', array('as' => 'admin.permissions.manage_entity', 'uses' => 'PermissionController#manage_entity'));
Route::post('{table}/{id}/permissions', 'PermissionController#update_permissions');
And the filters looks like:
Route::filter('admin', function()
{
$user = Sentry::getUser();
$action = Route::getCurrentRoute()->getAction();
if (!$user->hasAccess($action['as'])) return Redirect::to('/admin');
});
But now, all route inside that filter need a as declared or error will popup.
Hope this helps others.

Categories