如何创建用于身份验证的中间件



我正在尝试编写一个测试,以验证身份验证中间件是否在完成它的工作。正如我下面的代码所表明的,这个想法是,在未经身份验证的情况下,向该中间件内部的路由发出get请求,然后中间件应该将我重定向到登录视图,我会在测试结束时断言我正在被重定向。

但是,正如错误(最后一个"代码"(所示,我的测试不起作用,这是因为我的中间件什么都不做(什么也不做,我尝试过dd()echo等(,所以就好像我在发出get请求并实际访问路由返回的视图,而没有重定向到登录视图。

所以,如果我的代码缺少一些配置,如果它是错误的,或者提供任何其他帮助,有人能解释一下吗。

我的中间件:

<?php
namespace AppHttpMiddleware;
use Closure;
use IlluminateHttpRequest;
class AuthMiddleware
{
/**
* Handle an incoming request.
*
* @param  IlluminateHttpRequest  $request
* @param  Closure(IlluminateHttpRequest): (IlluminateHttpResponse|IlluminateHttpRedirectResponse)  $next
* @return IlluminateHttpResponse|IlluminateHttpRedirectResponse
*/
public function handle(Request $request, Closure $next)
{
if (!auth()->user()) {
return redirect(route('auth.get_login_view'), 301);
}
return $next($request);
}
}

内核:

protected $routeMiddleware = [
...
'authentication' => AppHttpMiddlewareAuthMiddleware::class,
];

我的路线:

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

我的测试:

public function a_user_is_redirected_if_not_authenticated()
{
$this->withoutExceptionHandling();
$response = $this->get(route('cms.users.index'));
$response->assertRedirect();
}

错误:

• TestsFeatureCmsUsersTest > 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

找到了解决方案。从Laravel 9开始,我的工作方式是将中间件添加到我的路由中,就像我下面所做的那样。

现在,我不知道这是否更多的是一种变通方法,而不是一种解决方案,因为在Kernel.php中注册我的中间件并导入它并使用它的类是很奇怪的。

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

最新更新