Use custom middleware in controller - php

I created middleware: php artisan make:middleware CheckUserStatus
In this middleware I have:
namespace App\Http\Middleware;
use Closure;
class CheckUserStatus
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(Auth()->check() AND Auth()->user()->status === 0) { // user is logged in but it is blocked
auth()->logout();
return redirect('/');
}
return $next($request);
}
}
Then, one of my controller I have:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Middleware\CheckUserStatus;
class productsController extends Controller
{
public function __construct () {
$this->middleware('auth');
$this->middleware('CheckUserStatus');
}
}
This gives ReflectionException - Class CheckUserStatus does not exist
What I'm doing wrong ?

You need to register your middleware if you want to reference it by a string key. Check out the docs here.
Alternatively, you could use the fully qualified class name: try CheckUserStatus::class instead of 'CheckUserStatus'.

You need to use the fully qualified class name:
Either:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class productsController extends Controller
{
public function __construct () {
$this->middleware('auth');
$this->middleware('\App\Http\Middleware\CheckUserStatus');
}
}
or
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Middleware\CheckUserStatus;
class productsController extends Controller
{
public function __construct () {
$this->middleware('auth');
$this->middleware(CheckUserStatus::class); //No quotes
}
}

You need to add your middleware in kernel.php
protected $routeMiddleware = [
'your_desire_name'=>\App\Http\Middleware\CheckUserStatus::class,
];

Related

Auth::check() works only in middleware laravel [duplicate]

I'm using Laravel 5.3 and I'm trying to get the authenticated user's id in the constructor method so I can filter the user by assigned company as follows:
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Facades\View;
use App\Models\User;
use App\Models\Company;
use Illuminate\Support\Facades\Auth;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests ;
public $user;
public $company;
public function __construct()
{
$companies = Company::pluck('name', 'id');
$companies->prepend('Please select');
view()->share('companies', $companies);
$this->user = User::with('profile')->where('id', \Auth::id())->first();
if(isset($this->user->company_id)){
$this->company = Company::find($this->user->company_id);
if (!isset($this->company)) {
$this->company = new Company();
}
view()->share('company', $this->company);
view()->share('user', $this->user);
}
}
However this doesn't return the user id. I've even tried Auth::check() and it doesn't work.
If I move the Auth::check() out of the __construct() method then this works as follows:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
dd(\Auth::check());
return view('home');
}
}
However this fails if I put this in the construct method in the HomeController too!
Any ideas why this is failing?
docs
you can't access the session or authenticated user in your
controller's constructor because the middleware has not run yet.
As an alternative, you may define a Closure based middleware directly
in your controller's constructor. Before using this feature, make sure
that your application is running Laravel 5.3.4 or above:
class ProjectController extends Controller
{
/**
* All of the current user's projects.
*/
protected $projects;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware(function ($request, $next) {
$this->projects = Auth::user()->projects;
return $next($request);
});
}
}
Since 5.3 Auth::check will not work in a controller's construtor, it's one of undocumented changes. So, you need to move it to middleware or do check in controller methods instead or move project to 5.2.x.
It fails because you call $this->middleware('auth'); after parent::__construct();. It means that you auth middleware is not loaded properly.

Add middleware to controller in __construct in Laravel

I am trying to assign a middleware in __construct of a controller based on Laravel docs but it throws the follwing error:
BadMethodCallException
Method App\Http\Controllers\MyController::middlware does not exist.
that is my controller class:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class MyController extends Controller
{
public function __construct()
{
$this->middleware('myauth');
}
/** something */
public function index()
{
return view('test.hi', ['name' => 'Moh']);
}
}
And here is the middleware code:
<?php
namespace App\Http\Middleware;
use Closure;
class myauth
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
echo time().'<br>';
return $next($request);
}
}
Laravel version: 6.5.2
Where am I doing wrong?
Middleware can be specified within controller's constructor
public function __construct() {
$this->middleware('auth');
}
For whole controller:
$this->middleware('auth');
Only for a particular action:
$this->middleware('auth')->only('index');
For whole controller except particular action:
$this->middleware('auth')->except('store');
The function is middleware, you have a typo, missing an e.
Firstly ask to you, Your error is middlware name is incoorect you missed e after that check the below middleware process.
Laravel Middleware - Middleware acts as a middleman between a request and a response.
Firstly goto project folder and open cmd and use this command
php artisan make:middleware MiddlewareName
after that go to App\Http\kernel.php and add one lines on $routeMiddleware
'user_block' => \App\Http\Middleware\MiddlewareName::class
After that goto your middleware
In handle function (write your own middleware code)
In routes use your middleware -
Route::group(['middleware' => ['user_block']],
function () {
Route::get('/logout', array('uses' => 'Auth\LoginController#logout'));
});
If you used this middleware in specific controller in __construct in any controller just write a line
namespace App\Http\Controllers;
use App\User;
class UserController extends Controller {
public function __construct() {
$this->middleware('user_block');
}
}
If you want this middleware for just one action in the controller you can add this middleware to the route :
Route::get('/login', 'LoginController#login')->middleware('user_block');
If you used this middleware in specific controller in specific 1-2 function just write this line in __construct functiono in controller
public function __construct()
{
$this->middleware('user_block')->only(['login','register']);
}

Share data with all views in Laravel?

I'm trying to share a collection of notifications to all views under the auth middleware. I thought I might be able to just call Auth::check() but it seems to always return false?
<?php
namespace App\Providers;
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;
use Auth;
class ViewServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
* #return void
*/
public function boot()
{
view()->composer('*', function ($view)
{
$view->with('userNotifications', Auth::user()->notifications);
});
}
}

Laravel 5.3 auth check in constructor returning false

I'm using Laravel 5.3 and I'm trying to get the authenticated user's id in the constructor method so I can filter the user by assigned company as follows:
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Support\Facades\View;
use App\Models\User;
use App\Models\Company;
use Illuminate\Support\Facades\Auth;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests ;
public $user;
public $company;
public function __construct()
{
$companies = Company::pluck('name', 'id');
$companies->prepend('Please select');
view()->share('companies', $companies);
$this->user = User::with('profile')->where('id', \Auth::id())->first();
if(isset($this->user->company_id)){
$this->company = Company::find($this->user->company_id);
if (!isset($this->company)) {
$this->company = new Company();
}
view()->share('company', $this->company);
view()->share('user', $this->user);
}
}
However this doesn't return the user id. I've even tried Auth::check() and it doesn't work.
If I move the Auth::check() out of the __construct() method then this works as follows:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Http\Response
*/
public function index()
{
dd(\Auth::check());
return view('home');
}
}
However this fails if I put this in the construct method in the HomeController too!
Any ideas why this is failing?
docs
you can't access the session or authenticated user in your
controller's constructor because the middleware has not run yet.
As an alternative, you may define a Closure based middleware directly
in your controller's constructor. Before using this feature, make sure
that your application is running Laravel 5.3.4 or above:
class ProjectController extends Controller
{
/**
* All of the current user's projects.
*/
protected $projects;
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware(function ($request, $next) {
$this->projects = Auth::user()->projects;
return $next($request);
});
}
}
Since 5.3 Auth::check will not work in a controller's construtor, it's one of undocumented changes. So, you need to move it to middleware or do check in controller methods instead or move project to 5.2.x.
It fails because you call $this->middleware('auth'); after parent::__construct();. It means that you auth middleware is not loaded properly.

Auth::check returns false in AppServiceProvider

I have tried injecting the Guard contract into the constructor, I have tried moving around. But when a user is logged in - Auth::check() returns false.
In other files (Except 1 global middleware) Auth::check() works correctly.
In the middleware - moving Auth Check to the top helped alleviate the issue. In this case - it isn't working.
Additional information: This app has been upgraded from 4.2 . Previously it used Confide.
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
if(Auth::check())
{
$user = Auth::user();
$messages=Message::where('read',0);
$messages->where(function ($query) use ($user) {
$query->where('to',$user->id)->orwhere('from',$user->id);
});
$message_unread= $messages->count();
$new_notifications= Notification::where('user_id',$user->id)->where('viewed',0)->count();
}
else
{
$message_unread=0;
$new_notifications=8888888;
//its 888888 for testing purposes.
}
view()->share(([
'message_unread'=>$message_unread,
'new_notifications'=>$new_notifications
]));
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
}
You should move this code to controller layer. boot method of Laravel's ServiceProviders serves for bootstrapping the services, not implementing busines logic.
You need to use auth in at the top of the serviceprovider class
use Auth;
Instead of
use Illuminate\Support\Facades\Auth;
Apart from using a view composer, you could also use middleware which is processed after the session variables have been loaded:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
class SetViewVariables
{
protected $auth;
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
public function handle($request, Closure $next)
{
$user = $this->auth->user();
view()->share('user', $user);
return $next($request);
}
}

Categories