今天遇到了一個(gè)小問題但是為了解決用了很久的時(shí)間,覺得有必要記錄一下這個(gè)過程使碾。
首先是設(shè)置了一個(gè)用于身份驗(yàn)證中間件Admin蜜徽,代碼如下:
public function handle($request, Closure $next) {
if(session('user')->user_group != 1){
$msg ="對不起,您無權(quán)訪問訪問本頁面!";
return view('error',compact('msg'));
}
return $next($request);
}
如果使用管理員身份登錄則一切正常,但是如果使用非管理員身份登錄則會(huì)出現(xiàn)一個(gè)錯(cuò)誤票摇。
搜索了很久終于在Laracasts發(fā)現(xiàn)有人有人針對這個(gè)錯(cuò)誤提問拘鞋,其中一個(gè)回答是
There are two types of middleware one that are applied to the global level and one that we apply to the route level. The route level middleware run inside the router's own local middleware stack. When we return some view from controller i.ereturn view('auth/login') the router's method dispatchToRoute explicitly prepares the Response object so that it can be used inside the global middleware (or in general can be returned to the browser). That said, only returning a view never prepares the response so the route lever middlewares throw such errors. you can fix it by simply returning a response rather then a rendered view.
由于英語水平不行并沒有完全看懂,個(gè)人理解是Laravel有兩種級別的中間件矢门,一種是應(yīng)用于全局級別的中間件一種是應(yīng)用于路由級別的中間件盆色,在只返回一個(gè)視圖時(shí)不會(huì)準(zhǔn)備響應(yīng),所以頭信息為空祟剔,導(dǎo)致setCookie()
無法調(diào)用隔躲。要修復(fù)這個(gè)問題應(yīng)該返回一個(gè)Response
對象,使用該類的view()
方法來取代直接返回一個(gè)渲染視圖物延。
//replace your `view returns` with `reponse returns` e.g:
return view('home.index')
//replace with
return response()->view('home.index')
而另一個(gè)回答則建議更好的處理方式是自己在中間件里準(zhǔn)備響應(yīng)
use Illuminate\Http\Response;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
..
public function handle($request, Closure $next) {
$response = $this->prepareResponse($request, $next($request));
if ($this->isReading($request) || $this->tokensMatch($request)) {
return $this->addCookieToResponse($request, $response);
}
throw new TokenMismatchException;
}
// this one is in fact a copy-paste from the Router
protected function prepareResponse($request, $response) {
if ( ! $response instanceof SymfonyResponse) {
$response = new Response($response);
}
return $response->prepare($request);
}
[原文鏈接][1] 以后有時(shí)間再深入研究
[1]:https://laracasts.com/discuss/channels/general-discussion/disable-global-verifycsrftoken-and-use-as-middleware-doesnt-work-setcookie-on-null