Home > Mobile >  How to create a middleware for authentication
How to create a middleware for authentication

Time:10-24

I am trying to write a test that verifies if an authentication middleware is doing its job. The ideia is, as my code bellow makes clear, to make a get request to a route inside this middleware while not authenticaticated, the middleware should then redirect me to the login view and I'd assert at the end of my test that I am being redirected.

But as the error (last "code") shows, my test is not working, and it's because my middleware does nothing (nothing at all, I've tried dd(), echo, etc), so it's as if I was making the get request and actually accessing the view the route returns, without being redirected to the login view.

So, can someone, please, explain me if my code lacks some configuration, if it's wrong, or give any other help.

My middleware:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class AuthMiddleware
{
  /**
   * Handle an incoming request.
   *
   * @param  \Illuminate\Http\Request  $request
   * @param  \Closure(\Illuminate\Http\Request): (\Illuminate\Http\Response|\Illuminate\Http\RedirectResponse)  $next
   * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse
   */
  public function handle(Request $request, Closure $next)
  {
    if (!auth()->user()) {
      return redirect(route('auth.get_login_view'), 301);
    }

    return $next($request);
  }
}

Kernel:

protected $routeMiddleware = [
   ...
    'authentication' => \App\Http\Middleware\AuthMiddleware::class,
  ];

My routes:

Route::as('auth.')->group(function () {
  Route::get('login', [AuthController::class, 'getUserTheLoginView'])->name('get_login_view');
  Route::prefix('auth')->group(function () {
    Route::post('login', [AuthController::class, 'loginUser'])->name('log_user');
  });
});

Route::middleware('authentication')->group(function () {
  Route::resources(['groups' => GroupsController::class]);
  Route::resources(['users' => UsersController::class]);
});

My test:

public function a_user_is_redirected_if_not_authenticated()
  {
    $this->withoutExceptionHandling();

    $response = $this->get(route('cms.users.index'));

    $response->assertRedirect();
  }

Error:

  • Tests\Feature\Cms\UsersTest > a user is redirected if not authenticated
  Expected response status code [201, 301, 302, 303, 307, 308] but received 200.
  Failed asserting that false is true.

  at tests/Feature/Cms/UsersTest.php:23
     19▕     $this->withoutExceptionHandling();
     20▕ 
     21▕     $response = $this->get(route('cms.users.index'));
     22▕ 
  ➜  23▕     $response->assertRedirect();
     24▕   }
     25▕ 
     26▕   /** @test */
     27▕   public function a_logged_user_can_create_another_user()


  Tests:  1 failed
  Time:   0.37s

CodePudding user response:

Found the solution. As of Laravel 9, the way that works for me is by adding the middleware to my routes as I did bellow.

Now, I don't know if this is more of a workaround rather than a solution, beacuse it's weird to have registered my middleware in the Kernel.php and also importing it and using its class.

...
use \App\Http\Middleware\AuthMiddleware;
...
Route::middleware(AuthMiddleware::class)->group(function () {
  Route::resources(['groups' => GroupsController::class]);
  Route::resources(['users' => UsersController::class]);
});
  • Related