3

I am developing a simple web application with Laravel 5.1 and my development environment is Homestead.

I have a view composer to pass Auth::user() data to admin panel related views automatically. Most general admin panel pages (Dashboard, Settings etc.) uses AdminController, and it extends Laravel's Controller. Specific admin panel pages (Users, Orders etc.) has their own controllers (Admin\UsersController, Admin\OrdersController respectively), which are extends AdminController.

No any middleware registered in routes for admin panel related routes, instead AdminController loads the auth middleware (which checks if registered user tries to load the page). And no other controller that extends AdminController overrides the constructor.

My problem is that if user is not logged in and tries to load an admin panel page (doesn't matter which one; Dashboard, Settings, Users, Orders - because the view composer called for every single one to pass Auth::user() data) there is no warning says "You are not authorized." or no redirection to login page, just an exception thrown which says Auth::user() is null.

Doesn't the auth middleware called first? If not what should I do to prevent the exception to be thrown (returning from view composer is not an elegant solution for my point of view by the way)?

Thanks in advance.


Addendum
  • AdminController

    <?php
    
    namespace App\Http\Controllers\Admin;
    
    use Illuminate\Http\Request;
    
    use App\Http\Requests;
    use App\Http\Controllers\Controller;
    
    class AdminController extends Controller
    {
        public function __construct()
        {
            // After middlewares
            $this->middleware("auth");
            $this->middleware("admin");
    
            // Before middlewares
            $this->middleware("no-cache");
        }
    
        /**
         * Display a listing of the resource.
         *
         * @return Response
         */
        public function index()
        {
            return view("admin.index");
        }
    }
    
  • Admin\OrdersController

    <?php
    
    namespace App\Http\Controllers\Admin;
    
    use Illuminate\Http\Request;
    
    use App\Http\Requests;
    use App\Http\Controllers\Controller;
    
    use App\Order;
    
    class OrdersController extends Controller
    {
        /**
         * Display a listing of the resource.
         *
         * @return Response
         */
        public function index()
        {
            $orders = Order::with("address")->get();
    
            return view("admin.orders.index")->with("orders", $orders);
        }
    }
    
  • ComposerServiceProvider

    <?php
    
    namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    
    use Auth;
    
    class ComposerServiceProvider extends ServiceProvider
    {
        /**
         * Bootstrap the application services.
         *
         * @return void
         */
        public function boot()
        {
            view()->composer("layouts.admin.default", function ($view) {
                $admin = Auth::user();
    
                $view->with([
                    "admin" => $admin,
                    "picture" => $admin->pictures[0]
                ]);
            });
        }
    
        /**
         * Register the application services.
         *
         * @return void
         */
        public function register()
        {
            //
        }
    }
    

Note: ComposerServiceProvider is registered in config/app.php.

ozanmuyes
  • 721
  • 12
  • 26

1 Answers1

2

Your Admin\OrdersController extends App\Http\Controllers\Controller, when it should extend App\Http\Controllers\Admin\AdminController. That's why you are not getting a redirection.

Hkan
  • 3,243
  • 2
  • 22
  • 27
  • Wow thanks for the heads-up, I missed that. But it's not the solution I was seeking for. When I try to load an admin panel page which "uses" `AdminController` (say Dashboard) I'm still facing with the peculiar problem of mine. Middlewares shouldn't be called before the view composers? – ozanmuyes Sep 11 '15 at 22:38
  • 1
    I'm not sure but, maybe it's because you are calling the middleware from the controller. I always add middlewares into the route like `Route::get('foo', ['middleware' => 'auth' /* the rest */ ]);` – Hkan Sep 11 '15 at 22:44
  • Yes that will do and also stated as [here](http://stackoverflow.com/questions/31065936/execution-order-of-middleware-in-laravel-5). One more question (because I feel lazy to dig into the documents right now) are middlewares written in `routes` file comma-separated? – ozanmuyes Sep 11 '15 at 22:50
  • That looks like a strange behavior but I'm sure Taylor has a reason for it. Just use route middlewares then. That solves your problem, right? – Hkan Sep 11 '15 at 22:55
  • Yes it solved my problem and the answer marked as Solution. Thanks. And to answer my latest question on comments, the document says "Use an array to assign multiple middleware to the route". – ozanmuyes Sep 11 '15 at 23:02