Laravel Middleware - how to execute inside a controller method? - php

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

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

how to get the roles and permissions dinamically - Laravel

I'm trying to implement roles and permissions for my laravel API. I installed the package:
https://yajrabox.com/docs/laravel-acl/3.0/introduction
It would be great if someone could explain to me how it works, all I want to do is get the permission when the user hits one API route.
I don't want to set the middleware in every route, because I'm going to do several routes and it would be a pain to set middleware every time, I want do it dynamically.
I tried to do it myself but it's not working. This is my code in Authserviceprovider:
public function boot(GateContract $gate)
{
$this->registerPolicies();
Passport::routes();
Passport::tokensExpireIn(Carbon::now()->addDays(15));
Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));
$permissions = Permission::with('roles')->get();
foreach ($permissions as $permission)
{
$gate->define($permission->name, function (User $user) use ($permission) {
return $user->hasPermission($permission);
});
}
}
I'm doing like this: https://github.com/laracasts/laravel-5-roles-and-permissions-demo/tree/master/app
You can use middleware within your web.php / api.php file such as my example (web.php) below:
Route::group(['middleware' => ['verified']], function () {
Route::get('/', 'HomeController#index')->name('home');
});
As my example shows, this will check an account is verified before allowing it to view '/'
Updated
This is almost irrelevant to the question above but as the Op asked a secondary question within the comments to my answer: here is my middleware code to show the Op how the middleware will function:
public function handle($request, Closure $next)
{
$verified = Auth::user();
if ($verified->verified == 0)
{
Auth::logout();
Session::flash('error', "$verified->username, your email address hasn't been verified yet therefore you're unable sign in.");
return Redirect('/login');
}
return $next($request);
}

Laravel: Check Permission for Each Controller

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.

LARAVEL 5.4 ROLE ON MIDDLEWARE

i'm trying to setup my role on routing using middleware, but everytime i log in into my system, it redirects back on my login view.
here is my routing
Route::group(['middleware' => ['auth','admin']],function(){
Route::get('dashboard','RouteController#adminDashboard');
Route::get('admin',function(){
return 'this is admin page';
});
});
and here is my middleware
public function handle($request, Closure $next)
{
if(Auth::User()->id_role == 1){
return $next($request);
}
return redirect::to('dashboard');
}
can u guys helpme.
You're missing the initial slash.
Route::group(['middleware' => ['auth','admin']],function(){
Route::get('/dashboard','RouteController#adminDashboard');
Route::get('/admin',function(){
return 'this is admin page';
});
})
Or inside your controllers declare a construct function like this:
public function __contstruct(){
$this->middleware('auth');
}
Followed by your usual functions
If login is successful then the middleware checks the id, if the id is 1 then you return the next request ($next($request);). Your redirect never occurs.
So the next request is handled by your adminDashboard function in RouteController.
You should return your view in RouteController like this:
public function adminDashboard() {
return view('your-path-to-your-dashboard');
}
and change your route to this
Route::get('/', 'RouteController#adminDashboard');

How to perform an "internal" redirect in Laravel 5.3

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!

Categories