由于刚刚入坑,也一直不断地给自己挖坑填坑。
此文涉及的绝大部分代码稳步这儿。
今天跟着视频教程做项目时,使用了多路由,由于想学着系统的写法,多学习一下。
于是就使用了如下多中间件,至于如何添加中间件,就不在这里赘述了,因为我没有完完整整的写一个中间件,所以用了两个中间件。
以下是我的路由的代码
Route::group(['middleware' => ['web', 'admin.login'], 'prefix' => 'admin', 'as' => 'admin.', 'namespace' => 'Admin'], function () { Route::get('index', 'IndexController@index'); Route::get('info', 'IndexController@info'); Route::post('logout', 'LoginController@getLogout') });
这里使用了web,admin.login两个中间件。但是我在操作admin.logout,点了一次退出,却发现退出到/home。经过检查发现是走到了这个文件里的路由。
app/Http/Middleware/RedirectIfAuthenticated.php
此代码内容如下
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\Auth; class RedirectIfAuthenticated { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @param string|null $guard * @return mixed */ public function handle($request, Closure $next, $guard = null) { if (Auth::guard($guard)->check()) { return redirect('/home'); } return $next($request); } }
这是一点<退出>而是先返回/home的原因。
最后经过不断的调试,发现问题出在了自己写的登录退出控制里。
由于自己把这个文件的全部写到了我自己的LoginController里,
app/Http/Controllers/Auth/LoginController.php
此文件的全部内容如下:
<?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\AuthenticatesUsers; class LoginController extends Controller { /* |-------------------------------------------------------------------------- | Login Controller |-------------------------------------------------------------------------- | | This controller handles authenticating users for the application and | redirecting them to your home screen. The controller uses a trait | to conveniently provide its functionality to your applications. | */ use AuthenticatesUsers; /** * Where to redirect users after login. * * @var string */ protected $redirectTo = '/home'; /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('guest')->except('logout'); } }
最后我发现我仿写的LoginController里把上面的内容基本全写了,
<?php namespace App\Http\Controllers\Admin; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Captcha; use App\Model\User; use Validator; use Auth; use Session; class LoginController extends Controller { /* |-------------------------------------------------------------------------- | Login Controller |-------------------------------------------------------------------------- | | This controller handles authenticating users for the application and | redirecting them to your home screen. The controller uses a trait | to conveniently provide its functionality to your applications. | */ use AuthenticatesUsers; /** * Where to redirect users after login. * * @var string */ protected $redirectTo = '/admin/index'; /** * Create a new controller instance. * * @return void */ /* public function __construct() { $this->middleware('guest')->except('logout'); }*/ public function getLogin() { return view('admin.login'); } //(此处省略) public function getLogout(Request $request) { $this->guard()->logout(); $request->session()->invalidate(); return redirect('/'); } }
但我注释了如下代码后发现可以正常退出了。
public function __construct() { $this->middleware('guest')->except('logout'); }
经过一夜的思考,恍然大悟。
使用了两层中间件[‘web’, ‘admin.login’],如果都使用了这个(以上那段代码),会导致程序像过安检门一样,一层层检测,点退出本来应该向传送一样,一下子到最外面的门里面,因为有这样重复的两段代码导致无法一下子传送到最外面的门那儿。
写在最后:(这才是本文的重点)
使用多层中间件时,不能有类似如下让程序跑偏的重复代码,我这里是在自己写的两个中间件里都用到了以下代码,由于中间件就像两道安检门,经过时都要进行判断,这是我退出时无法退出的原因,
public function __construct() { $this->middleware('guest')->except('logout'); }
》》》》点了退出后,注,我使用了两层中间件[‘web’, ‘admin.login’],他先经过web中间件,但是他判断到用户已经登录,所以他就直接放行了,当然跑到他指定的路由了,导致admin.login里的退出无法到达。
所以使用中间件要规范。要么自己用一个写的完整的中间件,例如像[web]中间一样,只使用一个中间件就不会出问题了。
多层中间件时,不要有冲突,那样会导致文件无法正常运行。