Send variable to terminate in middleware - laravel

I am trying to send a variable to terminate of middleware from route:
Route::group(['middleware' => 'checkUserLevel'], function () {
// my routes
});
I can get checkUserLevel in handle of middleware but I need to access in terminate method too, what should I do?
public function handle($request, Closure $next, $key)
{
dd($key); // it returns variable
}
public function terminate($request, $response)
{
//I need that variable here
}

As mentioned in documentation, if you would like to use the same instance of middleware (because by default it is using the fresh instance of middleware) you need to register the middleware as singleton.
You can register it as singleton by adding to your ServiceProvider's register method
public function register()
{
$this->app->singleton(\App\Http\Middleware\YourMiddleware::class);
}
Then you can use the class' property like the first example of lorent's answer
protected $foo;
public function handle($request, Closure $next)
{
$this->foo = 'bar';
return $next($request);
}
public function terminate($request, $response)
{
// because we cannot use `dd` here, so the example is using `logger`
logger($this->foo);
}

You can do:
protected $key;
public function handle($request, Closure $next, $key)
{
$this->key = $key;
}
public function terminate($request, $response)
{
$this->key; //access property key
}
even though this should be passed via request global. Like:
public function handle($request, Closure $next)
{
$request->input('key');
}
public function terminate($request, $response)
{
$request->input('key');
}
Edited:
Route::group(['middleware' => 'checkUserLevel'], function () {
Route::get('/test/{testparam}', function () {
});
});
public function handle($request, Closure $next)
{
$request->route('testparam');
}
public function terminate($request, $response)
{
$request->route('testparam');
}

I know this is ages old, but you could also use a static property. That saves you from having to register a singleton:
<?php
namespace App\Http\Middleware;
class MyMiddleware {
private static $key;
public function handle($request, Closure $next, $key)
{
self::$key = ($key); // it returns variable
}
public function terminate($request, $response)
{
$key = self::$key;
}
}
This works in my Laravel 5.8 application, don't see why it wouldnt' work anywhere else. Cannot say if there's any reason NOT to do this, but I don't know of one.
I'm using this myself to generate a Cache key in my handle function, and reuse the same key in my terminate function.

Related

debug adding header in middleware laravel

i added header in middleware and i want to check in my controller that header that i set exists or not . the problem i cant watch headers in controller debugging? how can i do that? anyway use case for this is cors problem
this is my middleware:
public function handle(Request $request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', '*');
}
and this is my controller:
public function action()
{
dd(request()->headers->get("Access-Control-Allow-Origin")); //always null
}
You need to call the set method:
public function handle(Request $request, Closure $next)
{
$request->headers->set('Access-Control-Allow-Origin', '*');
return $next($request);
}
Then you can retrieve the header:
public function action()
{
dd(request()->headers->get("Access-Control-Allow-Origin")); // *
}

Get Language from construct in laravel

i'm trying to get selected language in my construct to use in any function in that class:
my route:
Route::group(['prefix' => 'admin', 'middleware' => ['AdminMiddleWare','auth','localization']], function(){
Route::get('/', 'AdminController#index')->name('admin.index');
});
My Middleware:
public function handle($request, Closure $next)
{
if (Session::has('locale') AND array_key_exists(Session::get('locale'), Config::get('languages'))) {
App::setLocale(Session::get('locale'));
}
else {
App::setLocale(Config::get('app.locale'));
}
return $next($request);
}
My controller :
public $lang;
public function __construct()
{
$this->lang = Language::where('lang','=',app()->getLocale())->first();
}
public function index()
{
$lang = $this->lang;
return $lang;
}
but i'm getting only the default locale;
but if i change the controller to this:
public function index()
{
$lang = Language::where('lang','=',app()->getLocale())->first();
return $lang;
}
it will work...
how to get in construct and use it in all functions??
In Laravel, a controller is instantiated before middleware has run. Your controller's constructor is making the query before the middleware has had a chance to check and store the locale value.
There are multiple ways you can set up to work around this - the important thing is to make the call after middleware runs. One way is to use a getter method on your controller:
class Controller
{
/**
* #var Language
*/
private $lang;
public function index()
{
$lang = $this->getLang();
// ...
}
private function getLang()
{
if ($this->lang) {
return $this->lang;
}
return $this->lang = Language::where('lang','=',app()->getLocale())->first();
}
}

laravel terminable middleware, pass parameters from controller

I want to use a terminable middleware for request logging:
<?php
namespace Illuminate\Session\Middleware;
use Closure;
use App\Helpers\Logger;
class LogRequest
{
public function handle($request, Closure $next)
{
return $next($request);
}
public function terminate($request, $response)
{
Logger::log($request, $response, $additionalInfo)
}
}
How can I pass the $additionalInfo from the controller to the middleware?
EDIT:
Unfortunately the additional info is generated in the controller. I therefore cannot hard code it in the route middleware function
Have you try to add to kernel.php:
protected $routeMiddleware = [
......
'LogRequest'=> \App\Http\Middleware\LogRequest::class
];
in the LogRequestMiddleware:
public function handle($request, Closure $next, $additionalInfo)
{
//here you have $additionalInfo
$request->attributes->add(["info" => $additionalInfo]);
return $next($request);
}
public function terminate($request, $response)
{
dd( $request->attributes);
}
And in controller:
public function __construct()
{
$additionalInfo = "test"
$this->middleware("LogRequest:$additionalInfo");
}
I think you can set some attribute to the request object in your controller while handling it, and the request object itself will be passed to terminate($request, $response) as the first parameter. Then you can extract whatever you set in your controller and use it.
Edited: You might be able to do this
Controller
$request->attributes->add(['additionalInfo' => 'additionalInfoValue']);
Middleware
public function terminate($request, $response)
{
$additionalInfo = $request->attributes('additionalInfo' => $additionalInfo);
Logger::log($request, $response, $additionalInfo)
}

How to use the method on middleware laravel

this my middleware:
<?php
namespace App\Http\Middleware;
use Closure;
class CheckSession
{
public function handle($request, Closure $next)
{
return $next($request);
}
public function CheckSessionPageReuestTokenFailed($request, $next)
{
if ($request->session()->has('request_failed')) {
return $next($request);
} else {
echo 'forbidden';
}
}
}
how i can use method CheckSessionPageReuestTokenFailed($request, $next)?
thanks
Why you have written this method ?. you can write this code into handle method.
public function handle($request, Closure $next)
{
if ($request->session()->has('request_failed')) {
return $next($request);
} else {
echo 'forbidden';
}
}
and also you need register this middleware into $routeMiddleware array in
app/Http/Kernel.php file.
add this line:
'CheckSession' => CheckSession::class,
read laravel documentation to know more https://laravel.com/docs/5.4/middleware
public function handle($request, Closure $next)
{
$this->CheckSessionPageReuestTokenFailed($request, $next);
return $next($request);
}
You can use inside handle() method.
public function handle($request, Closure $next)
{
$this->CheckSessionPageReuestTokenFailed($request, $next);
return $next($request);
}

Middleware class not exist laravel

I am just learning laravel and I am facing one issue. I am trying to work with session but it is not working.
Middleware
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
class Adminlogin {
public function handle() {
if (!$request->session()->has('userid')) {
return view('admin.auth.login');
}
// return $next($request);
}
}
Error
ErrorException in Adminlogin.php line 10: Undefined variable: request
You should pass $request & $next in arguments like this:
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
class Adminlogin {
public function handle($request, Closure $next) {
if (!$request->session()->has('userid')) {
return view('admin.auth.login');
}
return $next($request);
}
}
See more about - Defining Middlewares in Laravel
Hope this helps!
Change it to:
public function handle($request, Closure $next) {
Also, you can simply use session() helper in your case:
public function handle($request, Closure $next) {
return session()->has('userid') ? $next($request) : view('admin.auth.login');
}

Resources