Laravel 5: Middleware before & after into routes - php

I have two Middlewares: beforeCache & afterCache, boths registered on Kernel.
I want to call them into routes in this order:
1. beforeCache
2. myController
3. afterCache
If I define a route like this:
Route::get('especies/{id}', [
'middleware' => 'beforeCache',
'uses' => 'MyController#myMethod',
'middleware' => 'afterCache',
]);
beforeCache don't executes because afterCache is redefining the same array key middleware.
How should I do that? Thanks!

I'll assume you're using 5.1 in this, but what you're doing is essentially trying to define an array of attributes on the route. The brackets [] are just a shorthand version of saying array(...).
From the documentation (http://laravel.com/docs/5.1/middleware#defining-middleware) specifically the Before / After Middleware you simply just need to return a certain way.
For Before middlewares you do your code and return the next request after your code executes.
public function handle($request, Closure $next)
{
// Perform action
return $next($request);
}
For After middleware you handle the rest of the request and then your code executes and finally return the response.
public function handle($request, Closure $next)
{
$response = $next($request);
// Perform action
return $response;
}
The route would end up looking like this,
Route::get('especies/{id}',[
'middleware' => [
'beforeCache',
'afterCache'
],
'uses' => 'MyController#myMethod'
]);

class BeforeMiddleware implements Middleware {
public function handle($request, Closure $next)
{
// Do Stuff
return $next($request);
}
}
class AfterMiddleware implements Middleware {
public function handle($request, Closure $next)
{
$response = $next($request);
// Do stuff
return $response;
}
}
1-The before middleware operates and then passes on the request.
2-The after middleware allows the request to be processed, and then operates on it

Related

Calling laravel controller inside a route

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

Laravel, add gate to see if user has access

I have got a table with my permissions, I want to be able to setup a route like below so that I check the logged in users permissions and see if they have got access to the edit_users page for example.
Route::group([ 'prefix' => 'users', 'middleware' => 'can:access,edit_users' ], static function() {
I have added the following Gate, where I would do my query and check, however $permission is null...
public function boot()
{
$this->registerPolicies();
Gate::define('access', static function ($user, $permission) {
dd($user, $permission);
});
}
How would I go about doing this? As I don't want to hard-code all the permissions into gates!
The default middleware passes a route parameter as the second argument. I think what you'll need to do in this case is write your own middleware that takes a string as the argument, then do your check manually.
namespace App\Http\Middleware;
use Closure;
class HasPermission {
public function handle($request, Closure $next, $permission)
{
if($request->user()->can('access', $permission)) {
return $next($request);
}
return redirect()->back();
}
}
Then register your new middleware in the kernel file
'hasPermission' => \App\Http\Middleware\HasPermission::class
Then you can use your new middleware instead of the can middleware in your route.
Route::group([ 'prefix' => 'users', 'middleware' => 'hasPermission:edit_users' ], function() {});

Laravel Middleware - how to execute inside a controller method?

I am using multiple views for the same URL, depending if the user is logged in or not.. so mywebsite.com is routed like this:
Route::get('/', 'HomeController#redirector')->name('home');
The controller is this:
public function redirector(){
if(!\Auth::check()){
return view('welcome');
}
else{
return $this->index();
}
}
Now, when it runs the index function I need it to run the middleware 'auth', that updates and checks the user. The problem is, I cannot attach it to the route, since they might be unlogged causing a redirection loop. I tried this:
public function redirector(){
if(!\Auth::check()){
return view('welcome');
}
else{
$this->middleware('auth');
return $this->index();
}
}
It does not run the middleware.
If I put it in the costructor method attaching it to index, like this:
$this->middleware('auth', ['only' => 'index'])
it also won't run.
Any solutions to this?
if(!\Auth::check()){..} //this returns false if a user is logged in, are you sure that's what you want?
If not then remove the '!'
You can also put the redirection logic in the middleware instead. If you are using the auth middleware that ships with Laravel this is already in place. You just have to modify it as below and place the middleware call in the constructor.
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->guest()) {
return redirect()->guest('login');
}
return $next($request);
}

How to pass URL parameter from route to middleware?

If I have middleware like:
<?php namespace App\Http\Middleware;
class SomeMiddleware
{
public function handle($request, Closure $next, $id = null)
{
//
}
}
In kernel.php:
'someMiddleware' => \App\Http\Middleware\SomeMiddleware::class,
In routes.php :
Route::put('post/{id}', ['middleware' => 'someMiddleware']);
How I can pass id captured in {id} to my middleware?
I know that I can pass some custom parameter like this:
Route::put('post/{id}', ['middleware' => 'someMiddleware:16']);
But in laravel documentation there is no described how to pass argument captured in route pattern.
I think that you can get the parameter from inside the middleware like this:
//your middleware's method
public function handle($request, Closure $next)
{
//get the ID
$id = $request->id
}

Laravel use route parameter in middleware

Couldn't find anything that specifically matches my situation. I have a route group defined as:
Route::group(['prefix' => 'api/v1/{access_token}'], function(){
...
}
The above group has several resource routes inside. I am trying to create a custom middleware that will validate the access_token parameter and return a 400 response if the parameter is not valid. I would like to be able to so something like this in my controllers:
class ProductController extends Controller {
/**
* Instantiate a new ProductController
*/
public function __construct()
{
$this->middleware('verifyAccessToken');
}
...
}
My question is not "how do I define custom middleware", but rather, how can I gain access to the access_token parameter from within the handle function of my custom middleware?
EDIT: While the question suggested as a duplicate is similar and has an answer, that answer seems to be outdated and/or unsatisfactory for what I am trying to accomplish.
You can just access it from your $request object using the magic __get method like this:
public function handle($request, Closure $next)
{
$token = $request->access_token;
// Do something with $token
}
http://laravel.com/docs/master/middleware#middleware-parameters
For simple
public function yourmethod($access_token){
$this->middleware('verifyAccessToken', $access_token);
}
I think you can't do it in __construct() method.
Just stick the middleware on the Route::group
Route::group(['prefix' => 'api/v1/{access_token}', 'middleware' => 'verifyAccessToken'], function(){
});
Then in your middleware, as Thomas Kim pointed out, you can use the $request object to gain access to the token that was passed to the route.
public function handle($request, Closure $next)
{
$token = $request->access_token;
// Do something with $token
}

Categories