How to alter all Request in laravel - laravel

I'm receiving requests from new front end which encrypt all of the post parameters
the previous frontend didn't encrypt the post parameters
however the current backend also doesn't decrypt the post parameters received
how do i alter the whole request received so that i can put the decryption first when calling the
$request->get('param_name');
so that when the value of param_name gets into the variables to be used, it's already decrypted
because modifying the whole backend 1 by 1 is really inefficient
i've ever alter the trans() function, just go the file that handles it and alter it
but on request
what is the file?

You can use middleware.
php artisan make:middleware RequestInterceptorMiddleware
Then in the handle method you can interrogate the request and perform a .merge()
if($request->has('param_name')) {
$request->merge(['param_name' => decrypt($request->get('param_name'))]);
}
return $next($request);
And then make sure to add that middleware to your Kernel.php in your corresponding route middleware declarations.

You need create middleware for you action.
php artisan make:middleware RequestDecryptMiddleware
In Kernel.php add:
<?php
// Kernel.php
protected $routeMiddleware = [
...
'decrypt' => \App\Http\Middleware\RequestDecryptMiddleware::class,
...
];
After it you can overide params in middleware:
public function handle($request, Closure $next)
{
if($request->has('encrypt_param')){
$request->merge(['encrypt_param' => decrypt_function($request->get('encrypt_param'))]);
}
return $next($request);
}
Then use it in you controller:
public function myAction(RequestDecryptMiddleware $request)...

Related

Laravel Custom Middleware

I am trying to achieve this using middleware
web.php
Route::get('/test', 'TestController#index')->middleware('TestLogin');
redirect to /test if session is found
Route::get('/test1', 'TestController#index1')->middleware('TestLogin');
redirect to test1 if session is set
Middleware -TestLogin
public function handle($request, Closure $next)`
{
if($request->session()->get('Username'))
{
return redirect()->route(\);
// what to write here to redirect to the path its being called from
}
return redirect()->route('login');
}
don't want to use default auth middleware
Your middleware is suppose to check the login (session), if it is not found then redirect to login page otherwise it should pass the request. Something like this:
public function handle($request, Closure $next)
{
// No login session, redirect
if(!$request->session()->get('Username'))
{
return redirect()->route('login');
}
// Pass the request down the rest of pipeline
return $next($request);
}
You should consider to use built in authentication system in Laravel itself, it will save you lots of code and you can be sure the auth is handled correctly in security point of view.

Laravel Policy not working on route middleware

I have a NotificationPolicy with the following code:
<?php
namespace App\Policies;
use App\Notification;
use App\User;
use Illuminate\Auth\Access\HandlesAuthorization;
class NotificationPolicy
{
use HandlesAuthorization;
public function update(User $user, Notification $notification)
{
return $user->id === $notification->user_id;
}
}
I have registered this properly by adding this to the AuthServiceProvider:
protected $policies = [
Notification::class => NotificationPolicy::class,
];
I have this so that only the logged in user can update their notification by doing things such as setting the archived_at value or read_at value to the current timestamp. The policy does work if I use it in the controller, i.e.;
class ArchiveItemController extends Controller
{
public function __invoke(Notification $notification)
{
$this->authorize('update', $notification);
$notification->markAsArchived();
return redirect()->route('inbox.index')->with('success', 'Item has been archived');
}
}
However I don't want to use them in the controllers and would prefer to use them in my routes file. So I have removed this line $this->authorize('update', $notification); from the controller and I have tried the following but it doesn't work:
Route::prefix('inbox')->middleware(['auth', 'can:employee'])->group(function () {
Route::get('/notification/{notification}/archive', 'User\Account\Inbox\ArchiveItemController')
->name('inbox.item.archive')
->middleware('can:update', 'notification');
});
I've even ran the following but they don't make a difference:
php artisan optimize
php artisan cache:clear
php artisan route:cache
php artisan view:clear
php artisan config:cache
Your middleware declaration is not correct.
You will have to change 'can:update', 'notification' to 'can:update,notification' for it to work:
So in the end you would have the following:
Route::prefix('inbox')->middleware(['auth', 'can:employee'])->group(function () {
Route::get('/notification/{notification}/archive', 'User\Account\Inbox\ArchiveItemController')
->name('inbox.item.archive')
->middleware('can:update,notification');
});
If you have cached the routes, you will have to run php artisan route:clear for the changes to take effect.
From the docs:
Laravel includes a middleware that can authorize actions before the
incoming request even reaches your routes or controllers. By default,
the Illuminate\Auth\Middleware\Authorize middleware is assigned the
can key in your App\Http\Kernel class. Let's explore an example of
using the can middleware to authorize that a user can update a blog
post:
use App\Post;
Route::put('/post/{post}', function (Post $post) {
// The current user may update the post...
})->middleware('can:update,post');
In this example, we're passing the can middleware two arguments. The
first is the name of the action we wish to authorize and the second is
the route parameter we wish to pass to the policy method. In this
case, since we are using implicit model binding, a Post model will be
passed to the policy method. If the user is not authorized to perform
the given action, a HTTP response with a 403 status code will be
generated by the middleware.

Auth::user() is null in new route

i'm using laravel 6 and have 2 route in my app; index and dashboard.
My routes/web is:
Auth::routes();
Route::middleware(['auth'])->group(function () {
Route::get('/index', 'todoApp\TodoController#index')->name('index');
Route::get('/dashboard', 'todoApp\Dashboard#dashboard')->name('dashboard');
});
i added dashboard route recently.
Auth::user() is null when i dump it in dashboard route but doesn't in index. What's the
Your Controller is instantiated before the middleware stack has ran; this is how Laravel can know what middleware you have set via the constructor. Because of this you will not have access to the authenticated user or sessions at this point. Ex:
public function __construct()
{
$this->user = Auth::user(); // will always be null
}
If you need to assign such a variable or access this type of information you would need to use a controller middleware which will run in the stack after the StartSession middleware:
public function __construct()
{
$this->middleware(function ($request, $next) {
// this is getting executed later after the other middleware has ran
$this->user = Auth::user();
return $next($request);
});
}
When the dashboard method is called, the middleware stack has already passed the Request all the way through to the end of the stack so all the middleware needed for Auth to be functioning and available has already ran at that point which is why you have access to Auth::user() there.
I think that this has something to do with the 'web' middleware. If you take a look into the Kernel.php (In app\Http) you will find the web middleware group.
This will show you that it actually calls a middleware called StartSession. Based on your route file (where web is not included as a middleware) I would think that you don't have a session in your Controller and there for no access to it.
I don't quite understand why this only happens in your /dashboard route, because the issue should also be in your /index route (unless you added the web middleware somewhere in your TodoController).
I think that this should do the trick:
Route::middleware(['web', 'auth'])->group(function () {
Route::get('/index', 'todoApp\TodoController#index')->name('index');
Route::get('/dashboard', 'todoApp\Dashboard#dashboard')->name('dashboard');
});
If you fire php artisan make:auth command.
It's doesn't matter where you define because of it's only define auth route
Route::middleware(['auth'])->group(function () {
Route::get('/index', 'todoApp\TodoController#index')->name('index');
Route::get('/dashboard', 'todoApp\Dashboard#dashboard')->name('dashboard');
});
Auth::routes();

How to execute code on every page load, but only after route controller executed?

I'm working on a Laravel based project and I need to execute some "basic" php code on every page load. Until now, I placed my code in boot() from AppServiceProvider. It works well, but I need to execute my "basic" code only after the code from route's controller has been already executed.
I've already searched in laravel's official docs, but I still did not figured out how to do it.
This is how my route looks:
Route::match(['get', 'post'], '/profile/email/{profile_id?}', 'profileController#profileHandleEmail')->name('profile/email');
The result I want to achive is to execute the code from profileController#profileHandleEmail before the "basic" code from AppServiceProvider.
Which would be the best way to do this? I guess it can't be achived using AppServiceProvider.
The suggested way to achieve what you want is to use middleware:
Run php artisan make:middleware PostProcess
It should generate the a middleware class under App\Http\Middleware
class PostProcess {
public function handle($request, $next) {
$response = $next($request);
// Run you code here.
return $response
}
}
Then modify your App\Http\Kernel.php middleware:
protected $middleware = [
//Existing entries
\App\Http\Middleware\PostProcess::class
];
That middleware will run after the response has been generated but before the response is sent to the client. If you want to run the code after the response was sent to the client you can use terminable middleware
class PostProcess {
public function handle($request, $next) {
return $next($request);
}
public function terminate($request, $response) {
//Your code here
}
}
Step1 : Create Middleware
php artisan make:middleware PostProcess
Step2 : Make a code which you need
class PostProcess {
public function handle($request, $next) {
if(condition){
you code here
}
return $next($request);
}
}
Step3 : Call middleware in kernel.php
protected $routeMiddleware = [
'admin' => \App\Http\Middleware\PostProcess::class,
];
Step 4: Call middleware in route file
Route::group(['middleware' => 'admin'], function() {
});

Listing middleware in kernel.php

I have an admin middlware AdminMiddleware.php
public function handle($request, Closure $next, $guard = null)
{
if(Auth::check())
{
if($request->user()->is_admin==1)
{
return $next($request);
}
return redirect('/login');
}
else
{
return redirect('/login');
}
}
And i have some routes under adminmiddleware:
Route::group(['middleware' => ['App\Http\Middleware\Adminmiddleware']], function () {
//admin routes
});
Working properly. And i'm litte confused on Registering middleware? Why should i register. Only for alias or something more effective?
For $routeMiddleware and $middlewareGroups, they are mostly for aliasing. As you mentioned, you can don't register it and use it just fine in your route file.
It's more on conveniency for your to swap the implementation shall you need to.
IMO, register it so that you can swap the middleware implementation at any point of time without going into your route configuration file to change it - which is more error prone than one central location to change.
Registering middleware is loading the class with each request automatically. You're telling Laravel to load and register it, so you could use it in routes and controllers without initializing it manually. Same with console commands, service providers etc. You must register before using them.
If you want a middleware to run during every HTTP request to your application, simply list the middleware class in the $middleware property of your app/Http/Kernel.php class.

Resources