How to remove query parameter from url in laravel via middleware? - php

I am using laravel and I am facing one problem, I have URL like this
https://example.com?version=2.2.0
Now I am creating middleware after matching the version the query parameter should remove.
Below is the middleware code
public function handle($request, Closure $next)
{
$input = $request->all();
$request->replace($request->except(['version']));
return $next($request);
}
But it is not working to remove query parameters although working post data.

Why don't use just remove method?
public function handle($request, Closure $next)
{
$input = $request->all();
$request->remove('version');
return $next($request);
}
This is what remove method does under the hood, in laravel source code:
/**
* Removes a parameter.
*/
public function remove(string $key)
{
unset($this->parameters[$key]);
}

Just unset the query param.
public function handle($request, Closure $next)
{
if( $request->has('version') ){
unset($request['version']);
}
return $next($request);
}

If i understand correctly you want to remove the ?version=2.2.0 from your url?
You can do this by using this code:
// This only works for GET requests, NOT for POST requests.
if ($request->has('version')) {
return redirect()->to($request->fullUrlWithoutQuery('version'));
}
return $next($request);

Related

Preloading middleware / response cache in Laravel?

I have some response values I'm caching using middleware in Laravel, like this:
public function handle($request, Closure $next)
{
$domain = parse_url($request->headers->get('origin'), PHP_URL_HOST);
$key = 'request|'.$domain.'|dashboard';
return cache()->rememberForever($key, function () use ($request, $next) {
return $next($request);
});
}
If values within that response function change, I'd like to reset the cache, and ideally pre-set it before any user experiences the load time.
However I'm not entirely sure how to go about that given that I'm setting the cache value as a closure - $next($request). Inherently, it is caching the actual serialized response.
Is there an easy way for me to mock this response programatically?
Edit: to clarify - the above functionality works fine, what I'd like is something like below:
public function resetCache($key)
{
// Clear out old cache:
cache()->forget($key);
// Preload new cache:
cache()->set($key, function ($request, $next) {
return $next($request);
});
}
Obviously the function above won't work since I have no context on $request or $next.
I'm starting to think I'm going about this the wrong way, inherently.
Try this:
public function handle($request, Closure $next)
{
$domain = parse_url($request->headers->get('origin'), PHP_URL_HOST);
$key = 'request|'.$domain.'|dashboard';
$response = $next($request);
if($response !== Cache:get($key)) {
Cache:forget($key);
}
return cache()->rememberForever($key, function () use ($reponse) {
return $response;
});
}

Add Multiple Middleware to Laravel Project

I'm new to laravel I have created middleware for my each role but when I add it to my route it won't work.
If I add single middleware to my route it works fine but when I add second and third one It will not work.
It won't shows the route to authorized user it redirect it to home,
My User Model:
public function IsAdmin()
{
if($this->role_id =='1')
{
return true;
}
else
{
return false;
}
}
public function IsManager()
{
if($this->role_id =='2')
{
return true;
}
else
{
return false;
}
}
public function IsUser()
{
if($this->role_id =='3')
{
return true;
}
else
{
return false;
}
}
My Kernal:
'IsAdmin' => \App\Http\Middleware\IsAdmin::class,
'IsManager' => \App\Http\Middleware\IsManager::class,
'IsUser' => \App\Http\Middleware\IsUser::class,
My IsAdmin Middlewares:
public function handle($request, Closure $next)
{
$user =Auth::User();
if(!$user->IsAdmin())
{
return redirect('stock');
}
return $next($request);
}
My IsManager
public function handle($request, Closure $next)
{
$user =Auth::User();
if(!$user->IsManager())
{
return redirect('stock');
}
return $next($request);
}
and IsUser
public function handle($request, Closure $next)
{
$user =Auth::User();
if(!$user->IsUser())
{
return redirect('stock');
}
return $next($request);
}
and finally my Route
Route::get('approv',['middleware'=>['IsManager','IsAdmin'],function(){
return view('approv');
}]);
This will not work as you'd expect. All middleware need to pass in order for the request to be processed which means that your user will need to be both a manager and an admin at the same time which based on your setup is impossible.
You can get around this (kind of) by making a different kind of middleware:
Kernel:
'roles' => \App\Http\Middleware\Roles::class,
And the Roles middleware:
class Roles {
private function checkRole($role) {
switch ($role) {
case 'user': return \Auth::user()->IsUser();
case 'manager': return \Auth::user()->IsManager();
case 'admin': return \Auth::user()->IsAdmin();
}
return false;
}
public function handle($request, Closure $next, ...$roles)
{
foreach ($roles as $role) {
if ($this->checkRole($role)) {
//At least one role passes
return $next($request);
}
}
//All checks failed so user does not have any of the required roles
return redirect('stock');
}
}
Then to use this you simply do:
Route::get('approv',['middleware'=>['roles:manager,admin'],function(){
return view('approv');
}]);
This works because Laravel Middleware support parameters. You can pass parameters as a comma separated list of strings where you declare the middleware. In this case this was done as roles:manager,admin
Laravel will then send these parameters as additional parameters in the handle method. These can be accessed using PHPs syntax for variadic arguments. In this particular case it's by using the array spread operator. This is documented as an example in the function arguments section of the PHP manual.
Note that this is actually equivalent to saying :
public function handle($request, Closure $next, $role1=null, $role2=null, $role3=null)
but using the spread operator is much more convenient since ...$roles would be an array which contains only the roles that were passed in the middleware.

Display request method (GET,POST, ..) in Laravel middleware

I have a middleware class in Laravel and I wanted to get the action name like (GET, POST, DELETE, PUT,...) for logging the information. I have below code:
public function handle($request, Closure $next)
{
$api_key = $request->headers->get('x-api-key');
if($api_key!=$this->auth_key){
return $this->response->unauthorize(
"You're not authorize to access. Make sure that you're passing your api Key"
);
}
return $next($request);
}
I have this line $request->route(); that may help but I don't know about the method.
use Illuminate\Routing\Route;
private $route;
public __construct(Route $route) {
$this->route = $route;
}
public function handle($request, Closure $next)
{
$action = $this->route->getMethods(); // return array
$api_key = $request->headers->get('x-api-key');
if($api_key!=$this->auth_key){
return $this->response->unauthorize(
"You're not authorize to access. Make sure that you're passing your api Key"
);
}
return $next($request);
}

How to retrieve a url parameter from request in Laravel 5?

I want to perform certain operations with a model in a middleware. Here is an example of what I want to achieve:
public function handle($request, Closure $next)
{
$itemId = $request->param('item'); // <-- invalid code, serves for illustration purposes only
$item = Item::find($itemId);
if($item->isBad()) return redirect(route('dont_worry'));
return $next($request);
}
My question is, how can I retrieve the desired parameter from the $request?
public function handle(Request $request, Closure $next)
{
$itemId = $request->item;
//..............
}
If the parameter is part of a URL and this code is being used in Middleware, you can access the parameter by it's name from the route given:
public function handle($request, Closure $next)
{
$itemId = $request->route()->getParameter('item');
$item = Item::find($itemId);
if($item->isBad()) return redirect(route('dont_worry'));
return $next($request);
}
This is based on having a route like: '/getItem/{item}'
Use this after Laravel 5.5
public function handle($request, Closure $next)
{
$item = Item::find($request->route()->parameter('item'));
if($item->isBad()) return redirect(route('dont_worry'));
return $next($request);
}

get request value in middleware laravel in handle function

public function handle($request, Closure $next) {
$login = new LoginController();
dd(Input::get('pass'));
if ($login->login_check()) {
if ($this->is_logged_in()) {
return $next($request);
} else {
return new RedirectResponse(url('/auth/login'));
}
}
//return $next($request);
}
This is my custom middleware. I want to get request value in handle function. I want to pass input field value.
I think you need to change Input::get('pass') to
Request::input('pass');
and remember to import the Request facade using a use Request; statement

Categories