Is there any way to access (modify) $request "protected proprieties" in the Middleware, to modify requested Controller:
public function handle($request, Closure $next)
{
// change $request parameter
// $request->server->parameters->REQUEST_URI = "something else";
return $next($request);
}
I want to override requested Controller if Cache is valid for the request,
thanks,
You can change the page in the middleware by returning a redirect.
public function handle($request, Closure $next)
{
// change $request parameter
// $request->server->parameters->REQUEST_URI = "something else";
if ($request->something === 'anything')
return redirect()->to("/something-else");
return $next($request);
}
Update:
If you do not wish for the url to update, you could invoke the controller directly using:
app(\App\Http\Controllers\MyController::class)->getMethod();
Where you update the Controller and the method to the ones you need.
However I would not recommend this.
Related
I've Laravel route with GET & POST as below
Route::get("test1","Api\TestController#test1");
Route::post("test1","Api\TestController#test1");
Now I'm trying to check some condition & if it remain true then I want to call controller else i want to show error without even going into controller.
Like:
Route::get("test1",function(){
$aaa=$_SERVER['REQUEST_URI'];
if(preg_match("/sender_id=TEST/is", $aaa)){
#Call_controller: "Api\TestController#test1"
}else{
echo "some error found"; die();}
});
How to call controller inside function of route.
I don't want to check this in controller because its a API & when i'm getting 10000+ hits per second, calling a function inside laravel load multiple dependences resulting wastage of server resources.
Same has to be done with GET & POST
While you can call the controller using (new Api\TestController())->test1(), the right way to do is:
Create a middleware (say "MyMiddleware") and add your logic in the handle() method:
public function handle($request, Closure $next)
{
$aaa=$_SERVER['REQUEST_URI'];
if (preg_match("/sender_id=TEST/is", $aaa)) {
return $next($request);
}
abort(403);
}
Now use the middleware in the route:
Route::get("test1","Api\TestController#test1")->middleware(MyMiddleware::class);
Since both your route functions are the same, you can use middleware.
Create check middleware php artisan make:middleware check
class check
{
public function handle($request, Closure $next)
{
if(preg_match("/sender_id=TEST/is", $request->getUri())) {
return $next($request);
}
else{
return "some error found";
}
}
}
And in route
Route::group(['middleware' => 'check'], function () {
Route::get("test1","Api\TestController#test1");
Route::post("test1","Api\TestController#test1");
});
I have a Middleware for Admin login where i am checking whether is user is admin or not. But now i want to check if an admin have permission to access the page or not. How can i do that?
My AdminMiddleware is:
public function handle($request, Closure $next)
{
if(Auth::check())
{
$user = Auth::user();
if($user->user_type=='employee')
{
return $next($request);
}
else
{
return redirect('/');
}
}
else
{
return redirect('/');
}
}
One way is to add the following code to each and every function of every controller.
if(Auth::user()->permission=='manage_employee'){
//code here
}
else
{
//redirect to access denied page
}
But this is not the correct way and time consuming. Is there any other way without using packages?
This is the proper way to use your middleware
Route::get('/your-url', 'YourController#yourFucntion')->middleware('admin');
Where admin is the name you register your middleware in your Kernel.php file :
to register it you have to insert this in $routeMiddleware part
'admin' => MustBeAdministrator::class,
If you wan to have different kind of admin check you can edit your route to pass a variable:
->middleware('admin:employee');
and you can get this variable in your middleware like this:
enter this below the comment #param \Closure $next :
#param string $permition
and modify your function:
public function handle($request, Closure $next, $permition)
Then use your permition variable in an if statement to do whatever you want to do.
I understand how to redirect users using redirect() method, but this method returns a 302 code and the browser must make a second HTTP request. Is it possible to internally forward the request to a different controller and action?
I'm doing this check in middleware so my handle function looks like this:
public function handle($request, Closure $next)
{
if (auth()->user->age <= 20) { //example
//internally forward the user to a different controller#action
}
return $next($request);
}
}
You can use call method as:
app()->call('App\Http\Controllers\ControllerName#funName')
Or
app('App\Http\Controllers\ControllerName')->funName();
So your middleware will look as:
if (auth()->user->age <= 20) {
return app()->call('App\Http\Controllers\ControllerName#action');
}
You can use redirect() helper method like this:
public function handle($request, Closure $next)
{
if (auth()->user->age <= 20) { //example
return redirect()->route('some_route_name');
}
return $next($request);
}
Inside your routes file, the route should be defined as:
Route::get('users/age/', 'ExampleController#method_name')->name('some_route_name');
Hope this helps!
I store some data in a middleware as following:
public function handle($request, Closure $next)
{
//checking above..
if($this->authed()){
$request->token= $token; //here store the token in user request
return $next($request);
}
return response('Invalid credentials', 401);
}
then in controller I call a custom request class
//function in controller
public function upload(CoverageValueRequest $request){ //calling a custom request
dd($request->token);
dd($request->all());
}
the first dd will give null. However if I changed CoverageValueRequest to Request it will print the token.
P.S: the $request data coming from REST call as JSON format using Content-Type: application/json. I am not sure if this is relevant.
update
I have changed the following in the middleware still same behavior:
$request->merge(['token' => $token]);
can't get the token if CoverageValueRequest but if it is Request then it works.
I have found the answer by setting token as attribute to request, the middleware class:
public function handle($request, Closure $next)
{
//checking above..
if($this->authed()){
$request->attributes->add(['token' => $token]);
return $next($request);
}
return response('Invalid credentials', 401);
}
then retrieve it in the controller as following:
//function in controller
public function upload(CoverageValueRequest $request){ //calling a custom request
dd($request->attributes->get('token'));
dd($request->all());
}
I am not sure why the weird behavior of direct assigning or merge didn't work. Hope someone can clarify.
I'm using Laravel 5.1 and am creating a "Admin" middleware to check that a user has right to access a specific page.
I would like to do this, but it doesn't work:
public function handle($request, Closure $next)
{
if ($this->auth->guest() or !$this->auth->user()->isAdmin())
return redirect()->guest('auth/signin');
return $next($request);
}
So I achieve my goal like this, but it seems weird:
public function handle($request, Closure $next)
{
if ($this->auth->guest() or ! User::find($this->auth->user()->id)->isAdmin())
return redirect()->guest('auth/signin');
return $next($request);
}
Any suggestion? Am I missing something?
I don't know but if you copied your code
!$this->auth->user-()->isAdmin()
, is error. After user you have "-()"
OKay, thank you for your help:
I had two User class (one in App\User and one ine App\Models\User). I changed my configuration in config/auth.php to set the model to App\Models\User::class and deleted the default User model present when installing Laravel. So now the isAdmin() function works.
And as xAoc told me, the code is now the following:
public function handle($request, Closure $next)
{
if (!$this->auth->user()->isAdmin())
return redirect()->guest('auth/signin');
return $next($request);
}