Check the user's auth in all controllers' actions - php

I use Laravel 5.3 and I have the following problem.
[UPDATE]
My initial trouble was the appearance of an error when performing actions on the site when the user was not logged in the system.
This happened when the browser is started, where cached information is displayed by default on the page. Site interface displayed for logged users, and in his system was not. At the same time, producing some action, I get an error that the user is not authorized.
I also have group auth middleware for all my routes. When I reboot page of the site, the middleware is activated and redirectedme to the login page. The main problem is the browser shows the cached information.
So, in addition to middleware for routes I decided to make auth check in controllers.
[/UPDATE]
I want to check user's auth in every controller's action. Making the auth check in every controllers' action manually isn't a solution, because there are many controllers and actions.
So I decided to make it globally.
As all controllers extends Main Controller (App\Http\Controllers\Controller.php), I decided write the
auth()->check() in constructor:
function __construct()
{
if(auth()->check()) dd('success');
}
But... nothing happened((( Then I found the callAction method in BaseController which Main Controller extends and made checking here:
public function callAction($method, $parameters)
{
if(auth()->check()) dd('success');
return call_user_func_array([$this, $method], $parameters);
}
This time everything's OK, but I don't like this solution, because editing the core files isn't good.
Finally, I redeclared callAction method in Main Controller with auth checking, but I don't like this way too.
Is any solution?

You should use middleware:
Route::get('profile', ['middleware' => 'auth', 'uses' => 'UserController#showProfile']);
Or:
Route::get('profile', 'UserController#show')->middleware('auth');
Or using middleware groups:
Route::group(['middleware' => ['auth']], function () {
// Controllers here.
});
Or using controller's construct:
public function __construct()
{
$this->middleware('auth');
}

You can use auth middleware in your controller
public function __construct()
{
$this->middleware('auth');
}
check here : https://laravel.com/docs/5.3/authentication

if there is a group of routes this would be the easiest way
Route::group(['middleware' => ['auth']], function()
{
// here all of the routes that requires auth to be checked like this
Route::resource('user','UsersController');
}
another ways
function __construct()
{
$this->middleware('auth');
}
another way is specified on controller routes
Route::get('profile', [
'middleware' => 'auth',
'uses' => 'UserController#showProfile'
]);
see documentation
https://laravel.com/docs/5.0/controllers#controller-middleware

Related

Is there any difference between assigning middleware in a route group and launching it in controler's constructor?

I am wondering if there is any adifference between asiigning middleware in a route like this :
Route::patch('/edit/{column}/{id}',['middleware' => 'auth', 'uses' => 'ResourceController#editCompany']);
and launching it in controller's constructor
public function __construct()
{
$this->middleware('auth');
}
Is it the same? Does it do anything else then checking if I am logged in?
It is completely the same. The problem is when you add that in the constructor you need to remember to add it in every new controller that you want to be auth protected.
While in the routes file, you can group multiple endpoints and apply the middleware in all of them:
Route::group(['middleware' => 'auth'], function() {
// all routes here that need to be auth protected.
});

Problem in my test function trying to access group of routes

What I'm trying to test is to access some routes but these routes are in laratrust role middleware this role is the auth user must be super admin to go in this routes my problem is I don't know how to write this function.
I tried to make the user super admin in the test function like this
public function Test()
{
$user = factory(User::class)->create();
$user->attachRole('superadministrator');
$this->actingAs($user, 'api');
$response = $this->json('GET', 'api/users');
$response->assertStatus(200);
}
but it didn't work even I checked the data base this user is superadministrator and the test give like I'm not super admin
This is my api routes:
Route::group(['middleware' => ['auth:api', 'role:superadministrator']],
function()
{
Route::apiResource('users', 'UserController');
}
This is my index function in UserController:
public function index()
{
return Response()->json(User::all, 200);
}
What I'm expect is a function can access this route because there is more routes in this group and the rest of the tests depends on this function
I've never used Laratrust, but after a quick look at its source code, it looks like the issue is that you need to specify the api guard on your role middleware check. Add ,guard:api to your role middleware:
Route::group(['middleware' => ['auth:api', 'role:superadministrator,guard:api']], function() {
Route::apiResource('users', 'UserController');
}
In the role middleware check, if you don't specify the guard, it will use the default guard defined in your auth config (which is web if you haven't changed it). So, the middleware will be looking for the user from the web auth guard, which doesn't exist.
The good news is, your test worked! It found a bug in your route definition.

Laravel - How to restrict certain functionality based on user authentication?

Laravel newbie here (obviously :D ). I've set up a new model & controller for a model named Pages.
Every User has many Pages.
Each Page has a single User.
I've created the following functioning controller actions (& views):
PagesController::index
PagesController::create
PagesController::store
PagesController::show
PagesController::edit
PagesController::delete
So you can edit a Page by going to url.dev/pages/{id}/edit.
The problem is, you can access all of these routes regardless of your session status. So random users can edit any given Page. Which, obviously, is terrible.
Can anyone point me in the direction of what I should read up on, to limit the ability to access my model's controller actions based on whether or not the user is logged in (and if it's the correct user, at all)?
To force a specific route to be only accessible by authenticated users you can specify middleware auth in the controller constructor, like so:
public function __construct()
{
$this->middleware('auth');
}
Also you can restrict which methods you want auth to be applied to in the controller, using the only or except parameters. Using only you could do:
public function __construct()
{
$this->middleware('auth', ['only' => ['create', 'store', 'edit', 'delete']]);
}
You´re looking for middleware..
You can read more here
public function __construct()
{
$this->middleware('auth')->only('index');
$this->middleware('admin')->except('store');
}
Other answers are good, but I prefer to use middleware on route groups.
So when I have several routes like this:
Route::get('pages', 'PagesController#index')->name('pages.index');
Route::get('pages/{id}/edit', 'PagesController#edit')->name('pages.edit');
I would add them inside Laravel Route group. Like this:
Route::group(['middleware' => 'auth'], function() {
Route::get('pages', 'PagesController#index')->name('pages.index');
Route::get('pages/{id}/edit', 'PagesController#edit')->name('pages.edit');
});

How to ensure user is authenticated before he publishes an article in Laravel in the below scenario?

I am developing a simple web blogging application in Laravel 5.1. The application contains two controllers, a UsersController and an ArticlesController.
The authenticate() and check() functions that validate whether the user is authorized to carry out the operation are in the UsersController, and the store(), update() etc. features related to articles are in the ArticlesController.
How am I supposed to call the authenticate() or check() function from ArticlesController before say, store()ing an article to the database?
Laravel uses middleware, in your controller you need to put this
public function __construct(){
$this->middleware('auth'); //Requires auth
}
and in your routes you need to add the code for use middleware in your needed controllers like this
Route::group(['middleware' => 'auth'], function () {
Route::get('/', function () {
// Uses Auth Middleware
});
Route::get('user/profile', function () {
// Uses Auth Middleware
});
});
Read the documentation of Laravel about Middleware you can create more middleware http://laravel.com/docs/master/middleware
You're question is not very clear, but I suppose that you want check if an user is authenticated before storing an article. There are many ways to do it:
Set a middleware in the routing rules of your ArticleController.
Check the authentication in the store method using the "standard" Auth class.
Example:
function store()
{
if (Auth::check())
{
// The user is logged in...
}
}

Protecting all admin/ routes with auth in Laravel

I am brand new to laravel and am setting up admin panel authorization on my first application. The way I have my files setup currently setup is:
controllers/
admin/
dashboard.php
settings.php
non-admin-controller1.php
non-admin-controller1.php
views/
admin/
dashboard.blade.php
login.blade.php
template.blade.php
non-admin-view1.php
non-admin-view1.php
non-admin-view1.php
...and these are my routes
Route::get('admin/login', function()
{
return View::make('admin.login');
});
Route::get('admin/logout', function()
{
return Auth::logout();
return Redirect::to('admin/login');
});
Route::post('admin/login', function()
{
$userdata = array('username' => Input::get('username'),
'password' => Input::get('password'));
if (Auth::attempt($userdata))
{
return Redirect::to('admin');
}
else
{
return Redirect::to('admin/login')->with('login_errors',true);
}
});
Route::controller('admin.dashboard');
Route::get('admin', array('before' => 'auth', function() {
return Redirect::to_action('admin#dashboard');
}));
Route::filter('auth', function()
{
if (Auth::guest()) return Redirect::to('admin/login');
});
When I go to /admin I am redirected to admin/login and asked to login which is exactly how I need it to work. Upon logging in I am redirected to admin/dashboard and it all looks good there too. I am having 2 problems however.
When I go to admin/logout I am logged out but greeted with a blank page (it's not redirecting to admin/login)
When logged out, if I go to admin/dashboard I am greeted with the error
Error rendering view: [admin.dashboard]
Trying to get property of non-object
What am I doing wrong here? What am I doing right? Would it make more sense to create a separate bundle for admin? Thanks!
So I was able to solve my problem a slightly different way. I created an (base) Admin_Controller in the root of the controllers folder, with a constructor calling the auth filter before execution:
class Admin_Controller extends Base_Controller {
public function __construct()
{
$this->filter('before', 'auth');
}
}
and then made all my admin related controllers in /controllers/admin extend Admin_Controller and call the parent constructor:
class Admin_Dashboard_Controller extends Admin_Controller {
public function __construct()
{
parent::__construct();
}
public function action_index()
{
return View::make('admin.dashboard');
}
}
This might not be the most eloquent solution, but it does the job!
In your admin/login route you have an unnecessary return before the Auth::logout() call, nuke that and it should fix it up.
Another issue here is that only your one 'admin' route is getting filtered. You could wrap all of your admin routes with a Route::group() and apply the 'auth' before filter or you could use Route::filter('pattern: admin/*', 'auth') too.
Check out:
http://laravel.com/docs/routing#filters
For the second issue, is your Admin Dashboard controller class named Admin_Dashboard_Controller and if so, do you have an action_index() or get_index() function in there returning a view?
Check out:
http://laravel.com/docs/controllers#nested-controllers
(I'm assuming you're using L3 here btw.)
For future readers, a very clean way to handle this is using Laravel's Route Groups:
Route groups allow you to share route attributes, such as middleware or namespaces, across a large number of routes without needing to define those attributes on each individual route.
Route::group(['middleware' => 'auth'], function () {
Route::get('/', function () {
// Uses Auth Middleware
});
Route::get('user/profile', function () {
// Uses Auth Middleware
});
});
They can be used not only for authentication, but also Namespaces, Sub-Domains, and more.

Categories