Laravel : run specific middleware after Auth middleware - laravel

I've created a middleware that should be run for every request so i added that to $middleware property of Http\Kernel . I've also used Auth::check() inside this middleware , so my middleware should be run after Auth middleware unless Auth::check() will not work, how should i do that?

As far as i understand, you have already do that.
You should put your code into Auth::check() statement like below:
<?php namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class Test
{
public function handle($request, Closure $next)
{
if (Auth::check()) {
// your logic here
}
return $next($request);
}
}

Related

How can I use multiple middlewares on the same route name in Laravel 9?

I want my /dashboard page to be a different panel in 2 different user types. And return to home screen if not logged in. I created 2 middlewares to check if logged in user is "employer" or "employee". Whatever I do, I can't seem to make it work, it's been 2 days. I created middlewares and routes by following some very sketchy tutorials, it may hurt your eyes, be aware.
My route:
Route::get('/dashboard', function () {
return view('welcome');
})->name('welcome');
Route::prefix('admin')->middleware([\App\Http\Middleware\isEmployer::class])->group( function () {
Route::get("/dashboard", function (){
return view("employer.dashboard");
})->name("dashboard");
});
Route::prefix('store')->middleware([\App\Http\Middleware\isEmployee::class])->group( function(){
Route::get("/dashboard", function (){
return view("employee.dashboard");
})->name("dashboard");
});
isEmployee middleware:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class isEmployee
{
public function handle(Request $request, Closure $next)
{
if(Auth::user())
{
if (Auth::user()->role == "employee")
{
return $next($request);
}
}
return response()->view('welcome');
}
}
isEmployer middleware :
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class isEmployer
{
public function handle(Request $request, Closure $next)
{
if(Auth::user())
{
if (Auth::user()->role == "employer")
{
return $next($request);
}
}
return response()->view('welcome');
}
}
What I want to achieve is:
if not logged in : return welcome view
if logged in as employer : return employer.dashboard view
if logged in as employee : return employee.dashboard view
Let's start from some refactoring:
Make your routes/web.php a bit more readable:
Route::view('/dashboard', 'welcome')->name('welcome');
Route::prefix('admin')->name('admin.')->middleware('role:employer')->group(function() {
Route::view('/dashboard', 'employer.dashboard')->name("dashboard");
});
Route::prefix('store')->name('store.')->middleware('role:employee')->group(function() {
Route::view('/dashboard', 'employee.dashboard')->name("dashboard");
});
Now let's create a middleware that will check not only for one role, but for any role you give as a parameter:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class HasRole
{
public function handle(Request $request, Closure $next, string $role)
{
if (Auth::user()?->role != $role) {
return redirect()->route('welcome');
}
return $next($request);
}
}
Now, create an alias in your app/Http/Kernel.php so you could use it like i wrote it in routes file role:<role_here>:
protected $routeMiddleware = [
// ...
'role' => \App\Http\Middleware\HasRole::class,
];
Now for your question - how to use multiple middlewares for one route. It is simple:
$route->middleware(['middleware1', 'middleware2']);
You may attach them to groups or single routes:
Route::prefix('some_group')->middleware(['middleware1', 'middleware2'])->group(function() {
Route::view("some.view")->middleware('middleware3')->name("some.view");
});
You can read more info about Laravel's middlewares here, and understand what responsibility chain is (pattern which middleware implements) under the hood. Also take a look at SOLID principles, mainly at DRY one. Have a good day =)

Laravel api routes not working, it's always redirecting

I am having an issue with laravel doing my backend Api.
What I am trying to do is return logged user data with Auth::user();
I wrote the controller, the route for the controller method in api.php but when I try to go to the /api/route I am redirected to Home.
I also tried to remove the __construct() method from the controller, When I do this and try to go to the /api/route, dd($user) is returning null.
My controller:
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Resources\TeacherResource;
use Illuminate\Support\Facades\Auth;
class teacherApiController extends Controller
{
public function __construct(){
$this->middleware('auth');
}
public function information(){
$user = Auth::user();
dd($user);
}
}
Api.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::get('information', 'API\teacherApiController#information');
Anything I am doing wrong?
I am using the laravel authentication for register and login users.
I suppose you are not authenticated before calling this route that's why when the __construct was there it redirected you to the home, that's also why Auth::user() returns you null.
You are probably not authenticated before calling this route.
To manage the authentication you used laravel passport or even used JWT

Laravel,Can I use auth('api')->user() in Middleware?

I Would like to use auth('api')->user() in Middleware ,But felt that it wouldn't work.
And I don't use Auth::check() Because it Return null
P.S. auth('api')->user() Can use in my Controller.
-This code check online/offline user-
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Carbon\Carbon;
class LastUserActivity
{
public function handle($request, Closure $next)
{
$user = auth('api')->user();
if (isset($user)) {
$expiresAt = Carbon::now()->addMinutes(1);
Cache::put('user-is-online-' . $user->ID, true, $expiresAt);
}
return $next($request);
}
}

Laravel load middleware in routes under condition

I have a route files for my api and im using this package to cache the whole response.
routes/api.php
<?php
Route::get('/types', 'TypeController#indexType')->middleware('cacheResponse:600');
This works fine but i need to skip this middleware loading when i have a specific header in the request so i make this extra middleware
conditionalCacheResponse.php
<?php
namespace App\Http\Middleware;
use Closure;
class ConditionalCacheResponse
{
public function handle($request, Closure $next)
{
if (request()->header('Draft') != true) {
$this->middleware('cacheResponse:3600');
}
return $next($request);
}
}
and setup like this
routes/api.php
<?php
Route::get('/types', 'TypeController#indexType')->middleware('conditionalCacheResponse');
But is not working, im not sure if i can append a middleware in this way.
There's a few ways to do this, one way would be to use the handle() method of the HttpKernel to unset the CacheResponse middleware based on a check of the request header.
So in app/Http/Kernel.php, add this method:
public function handle($request)
{
if ($request->header('Draft')) {
if (($key = array_search('Spatie\ResponseCache\Middlewares\CacheResponse', $this->middleware)) !== false) {
unset($this->middleware[$key]);
}
}
return parent::handle($request);
}
I haven't checked this is working, but it should do the job.

Laravel set cookie not working

I have the following code in a custom middleware:
public function handle($request, Closure $next)
{
if($request->hasCookie('uuid')) {
return $next($request);
}
$uuid = 99;
$response = $next($request);
return $response->withCookie(cookie()->forever('uuid', $uuid));
}
I have registered the middleware in the app.php file, but cookies is still not being written. Please can anyone help. Additionally can this above be run as a singleton, so that it is executed once on app start?
Thanks
If you are on a local environment, make sure to set 'secure' => env('SESSION_SECURE_COOKIE', false), around lines #165-170 in your config/session.php file.
On a non-SSL domain (like http://localhost/), this directive must be false. Otherwise cookies will not be set in browser.
Here, I'm mention set and get a cookie in laravel simple example following.
First of the create a controller.
1.php artisan make:controller CookieController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use App\Http\Requests;
use App\Http\Controllers\Controller;
class CookieController extends Controller {
**/* below code a set a cookie in browser */**
public function setCookie(Request $request){
$response = new Response('Hello World');
$response->withCookie(cookie('name', 'Anything else'));
return $response;
}
**/* below code a get a cookie in browser */**
public function getCookie(Request $request){
$value = $request->cookie('name');
echo $value;
}
}
Add a following line code in routes/web.php file (Laravel 5.4)
Route::get('/cookie/set','CookieController#setCookie');
Route::get('/cookie/get','CookieController#getCookie');
And all files add-in project than a run program easily sets and get a cookie.
You can obtain the response object in middleware like so:
public function handle($request, Closure $next)
{
$response = $next($request);
// Do something after the request is handled by the application
return $response;
}
So you could do something like this
if($request->hasCookie('uuid')) {
return $next($request);
}
$uuid = Uuid::generate();
$response = $next($request);
return $response->withCookie(cookie()->forever('uuid', $uuid));
You can use the laravel helper function cookie(). This worked for me.
<?php
//Create:
cookie()->queue(cookie($name, $value, $minutes));
// forever
cookie()->queue(cookie()->forever($name, $value));
//get
request()->cookie($name);
//forget
cookie()->queue(cookie()->forget($name));

Resources