由于刚刚入坑,也一直不断地给自己挖坑填坑。
此文涉及的绝大部分代码稳步这儿。
今天跟着视频教程做项目时,使用了多路由,由于想学着系统的写法,多学习一下。
于是就使用了如下多中间件,至于如何添加中间件,就不在这里赘述了,因为我没有完完整整的写一个中间件,所以用了两个中间件。
以下是我的路由的代码
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]中间一样,只使用一个中间件就不会出问题了。
多层中间件时,不要有冲突,那样会导致文件无法正常运行。
达维营-前端网