get request value in middleware laravel in handle function - php

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

Related

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

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);

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.

How to check user Permissions using Custom Middleware in Laravel

I'm developing a Laravel ACL System. My base Table's are users,roles,permissions and pivot tables are role_user,role_permission,user_permission.
I want to check User Permissions using my custom middleware HasPermission. I have tried this way but it's not working properly. every user can access the all the permissions which have or have not.
Now, How can I solve the issue. Please see my code sample.
My Controller.
function __construct()
{
$this->middleware('auth');
$this->middleware('HasPermission:Role_Read|Role_Update|Role_Delete');
}
My Middleware.
class HasPermission
{
public function handle($request, Closure $next,$permissions)
{
$permissions_array = explode('|', $permissions);
// $user = $this->auth->user();
foreach($permissions_array as $permission){
if(!$request->user()->hasPermission($permission)){
return $next($request);
}
}
return redirect()->back();
}
}
and, my User Model method.
public function user_permissions()
{
return $this->belongsToMany(Permission::class,'user_permission');
}
public function hasPermission(string $permission)
{
if($this->user_permissions()->where('name', $permission)->first())
{
return true;
}
else
{
return false;
}
}
Best way to do is that you need to introduce an new service provider and in that you can check the authorization and permissions.
I made a test project (last year) for db driven permission and I used service provider.
That's the perfect way to implement.
Basically !$request->user()->hasPermission($permission) is saying if the user associated with the request does not have this permission the middleware passes, however this is not what you want. Here's what you should do:
If you need the user to have one of the stated permissions you need to do:
class HasPermission
{
public function handle($request, Closure $next,$permissions)
{
$permissions_array = explode('|', $permissions);
foreach($permissions_array as $permission){
if ($request->user()->hasPermission($permission)){
return $next($request);
}
}
return redirect()->back();
}
}
If you want the user to have all stated permissions you need to do:
class HasPermission
{
public function handle($request, Closure $next,$permissions)
{
$permissions_array = explode('|', $permissions);
foreach($permissions_array as $permission){
if (!$request->user()->hasPermission($permission)){
return redirect()->back();
}
}
return $next($request);
}
}
As an added note if you want to do this in a more elegant way you can do:
class HasPermission
{
public function handle($request, Closure $next, ...$permissions_array)
{
//Function body from above without the explode part
}
}
And
function __construct()
{
$this->middleware('auth');
$this->middleware('HasPermission:Role_Read,Role_Update,Role_Delete');
}
If you use commas then the framework will split the string into arguments for you .
In my case i just added simple function to get permissions from database and then check it Middleware. Check this code:
// Add new function to get permissions from database
public static function user_permissions($user) {
$permissions=DB::table('permissions')->where('user_id', $user)->first();
return $permissions;
}
// In Middleware check your permissions
if(Auth::guest())
{
return redirect('/');
}
elseif(Functions::user_permissions(Auth::user()->id)->user_managment != 1) {
return redirect('/');
} else {
return $next($request);
}
In web.php/api.php:
Route::middleware('hasPermission')->group(function() { // for all routes
Route::get('/article', [ArticleController::class, 'index'])->name('article.index');
});
in middleWare:
class HasPermission
{
public function handle($request, Closure $next)
{
$routeName = Request::route()->getName();
$permission = $user->permissions()->where('route_name', $routeName)->first();
if ( ! empty($permission)){
return redirect()->back();
}
return $next($request);
}
}

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);
}

Laravel: where I can override laravel code before response is returned?

I want override laravel at place where response is returned. Then I want to detect status code(200 or 301) and if request is ajax. If status code is 200 and request is ajax I want to return custom html. Something like
:
protected function returnResponse($statusCode, $html, $redirectUrl){
if($statusCode == 200 && isAjax()){
return parent::returnResponse($customStatusCode, $customHtml, $customRedirectUrl);
}
return parent::returnResponse($statusCode, $html, $redirectUrl);
}
EDITED:
I have this:
class SomeMiddleware
{
public function handle($request, Closure $next)
{
// do before
$request = $next($request);
//do after
return $request;
}
}
But how to detect if current response is redirect ?
If you want to inspect the final response and possibly return an alternate response, let's write a simple middleware.
It sounds like you want to do your checks at the end, after the default response has been built (so you can examine it). So we'll start like this:
// First get the default response
$response = $next($request);
Our $response variable will now hold the response Laravel is about to respond with.
If you want to see if the response is a redirect, you can easily check for a RedirectResponse instance:
$isRedirect = $response instanceof \Illuminate\Http\RedirectResponse;
You can test to see if the original request is ajax quite simply:
$isAjax = $request->ajax();
If you want to now return a different response instead of the one you were handed, I'd use the simple response() helper method:
return response($content, $status);
Putting it together, I believe this is roughly what you're looking for:
use Illuminate\Http\RedirectResponse;
class HijackMiddleware
{
public function handle($request, Closure $next)
{
$response = $next($request);
if($request->ajax() && $response instanceof RedirectResponse) {
return response("This is a <strong>different and custom</bold> response");
}
return $response;
}
}
My final solution :
<?php
namespace App\Http\Middleware;
use Closure;
use Response;
use Request;
class AjaxForm
{
public function handle($request, Closure $next, $guard = null)
{
$response = $next($request);
if(Request::ajax() && $response->status() == 301) {
return (Response::make($response->getTargetUrl(), '200'));
}
return $response;
}
}

Categories