如果请求授权在 Laravel 5.5 中失败则重定向
Redirect if request authorization is failed in Laravel 5.5
如果授权失败,我正在尝试重定向请求。我有以下代码:
class ValidateRequest extends Request{
public function authorize(){
// some logic here...
return false;
}
public function rules(){ /* ... */}
public function failedAuthorization() {
return redirect('safepage');
}
}
默认情况下我被重定向到 403 错误页面,但我想指定一些特定的路由。我注意到 failedAuthorization()
方法是 运行,但是 redirect()
方法不起作用...
以前此代码与 Laravel 5.1 配合使用效果很好,但我使用 forbiddenResponse()
方法重定向错误的请求。我如何使用新的 LTS 版本修复它?
我认为你可以通过 middleware/policy 来完成。我不知道你是否可以从验证中做到这一点。
您可以像下面这样重写 FormRequest 中的函数:
/**
* Handle a failed authorization attempt.
*
* @return void
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
protected function failedAuthorization()
{
throw new AuthorizationException('This action is unauthorized.');
}
然后重定向到你想要的地方。
看起来不可能直接从自定义 ValidateRequest
class redirect()
。我找到的唯一解决方案是创建自定义异常,然后在处理程序 class 中处理它。所以,现在它适用于以下代码:
更新: 方法 redirectTo()
已更新,使解决方案适用于 Laravel 6.x 和更高
app/Requests/ValidateRequest.php
class ValidateRequest extends Request{
public function authorize(){
// some logic here...
return false;
}
public function rules(){
return [];
}
public function failedAuthorization() {
$exception = new NotAuthorizedException('This action is unauthorized.', 403);
throw $exception->redirectTo("safepage");
}
}
app/Exceptions/NotAuthorizedException.php
<?php
namespace App\Exceptions;
use Exception;
class NotAuthorizedException extends Exception
{
protected $route;
public function redirectTo($route) {
$this->route = $route;
abort(Redirect::to($route));
}
public function route() {
return $this->route;
}
}
和app/Exceptions/Handler.php
...
public function render($request, Exception $exception){
...
if($exception instanceof NotAuthorizedException){
return redirect($exception->route());
}
...
}
所以,它有效,但比我预期的要慢得多...简单的测量表明处理和重定向需要 2.1 秒,但是 Laravel 5.1 相同的操作(和相同的代码)只需要 0.3 s
将 NotAuthorizedException::class
添加到 $dontReport
属性 根本没有帮助...
更新
php 7.2 运行速度更快,需要 0.7 秒
如果您正在重新访问此线程,因为在 2021 年您希望在授权失败后重定向,您可以执行以下操作:
您不能从 failedAuthorization() 方法重定向,因为它会抛出异常(检查您扩展的基本 FormRequest class 中的方法),更改的副作用return 类型是 $request 命中控制器而不是在 FormRequest 授权级别上处理。
您不需要创建自定义异常 class,也不需要像编辑 app/Exceptions/Handler 的 render() 那样干预 Laravel 核心文件。php,这将拾取您抛出的异常并默认呈现乏味的 403 页面。
你需要做的就是抛出新的 HttpResponseException()
在Laravel reference API中我们可以看到它的工作是“创建一个新的HTTP响应异常实例”。这正是我们想要的,对吧?
因此我们需要将此异常传递给 $response。我们可以传递重定向或 JSON 响应!
重定向:
protected function failedAuthorization()
{
throw new HttpResponseException(response()->redirectToRoute('postOverview')
->with(['error' => 'This action is not authorized!']));
}
所以我们正在创建一个新的 HttpResponseException 实例,我们使用 response() helper,它有这个超级有用的 redirectToRoute('routeName') 方法,我们可以进一步将它与众所周知的链接起来() 方法并传递错误信息显示在前端。
JSON:
受此启发 topic
throw new HttpResponseException(response()->json(['error' => 'Unauthorized action!'], 403));
就是这样。
您不必在控制器中进行任何验证或授权检查,一切都在到达控制器之前在后台完成。您可以通过放置 dd('reached controller'); 来测试它在你的控制器方法的顶部,它不应该被触发。
这样你就可以让你的控制器保持精简和独立的关注点:)
旁注:
forbiddenResponse() 在 lara 5.4 之后被替换为 failedAuthorization()
如果授权失败,我正在尝试重定向请求。我有以下代码:
class ValidateRequest extends Request{
public function authorize(){
// some logic here...
return false;
}
public function rules(){ /* ... */}
public function failedAuthorization() {
return redirect('safepage');
}
}
默认情况下我被重定向到 403 错误页面,但我想指定一些特定的路由。我注意到 failedAuthorization()
方法是 运行,但是 redirect()
方法不起作用...
以前此代码与 Laravel 5.1 配合使用效果很好,但我使用 forbiddenResponse()
方法重定向错误的请求。我如何使用新的 LTS 版本修复它?
我认为你可以通过 middleware/policy 来完成。我不知道你是否可以从验证中做到这一点。
您可以像下面这样重写 FormRequest 中的函数:
/**
* Handle a failed authorization attempt.
*
* @return void
*
* @throws \Illuminate\Auth\Access\AuthorizationException
*/
protected function failedAuthorization()
{
throw new AuthorizationException('This action is unauthorized.');
}
然后重定向到你想要的地方。
看起来不可能直接从自定义 ValidateRequest
class redirect()
。我找到的唯一解决方案是创建自定义异常,然后在处理程序 class 中处理它。所以,现在它适用于以下代码:
更新: 方法 redirectTo()
已更新,使解决方案适用于 Laravel 6.x 和更高
app/Requests/ValidateRequest.php
class ValidateRequest extends Request{
public function authorize(){
// some logic here...
return false;
}
public function rules(){
return [];
}
public function failedAuthorization() {
$exception = new NotAuthorizedException('This action is unauthorized.', 403);
throw $exception->redirectTo("safepage");
}
}
app/Exceptions/NotAuthorizedException.php
<?php
namespace App\Exceptions;
use Exception;
class NotAuthorizedException extends Exception
{
protected $route;
public function redirectTo($route) {
$this->route = $route;
abort(Redirect::to($route));
}
public function route() {
return $this->route;
}
}
和app/Exceptions/Handler.php
...
public function render($request, Exception $exception){
...
if($exception instanceof NotAuthorizedException){
return redirect($exception->route());
}
...
}
所以,它有效,但比我预期的要慢得多...简单的测量表明处理和重定向需要 2.1 秒,但是 Laravel 5.1 相同的操作(和相同的代码)只需要 0.3 s
将 NotAuthorizedException::class
添加到 $dontReport
属性 根本没有帮助...
更新
php 7.2 运行速度更快,需要 0.7 秒
如果您正在重新访问此线程,因为在 2021 年您希望在授权失败后重定向,您可以执行以下操作:
您不能从 failedAuthorization() 方法重定向,因为它会抛出异常(检查您扩展的基本 FormRequest class 中的方法),更改的副作用return 类型是 $request 命中控制器而不是在 FormRequest 授权级别上处理。
您不需要创建自定义异常 class,也不需要像编辑 app/Exceptions/Handler 的 render() 那样干预 Laravel 核心文件。php,这将拾取您抛出的异常并默认呈现乏味的 403 页面。
你需要做的就是抛出新的 HttpResponseException() 在Laravel reference API中我们可以看到它的工作是“创建一个新的HTTP响应异常实例”。这正是我们想要的,对吧?
因此我们需要将此异常传递给 $response。我们可以传递重定向或 JSON 响应!
重定向:
protected function failedAuthorization()
{
throw new HttpResponseException(response()->redirectToRoute('postOverview')
->with(['error' => 'This action is not authorized!']));
}
所以我们正在创建一个新的 HttpResponseException 实例,我们使用 response() helper,它有这个超级有用的 redirectToRoute('routeName') 方法,我们可以进一步将它与众所周知的链接起来() 方法并传递错误信息显示在前端。
JSON: 受此启发 topic
throw new HttpResponseException(response()->json(['error' => 'Unauthorized action!'], 403));
就是这样。 您不必在控制器中进行任何验证或授权检查,一切都在到达控制器之前在后台完成。您可以通过放置 dd('reached controller'); 来测试它在你的控制器方法的顶部,它不应该被触发。 这样你就可以让你的控制器保持精简和独立的关注点:)
旁注: forbiddenResponse() 在 lara 5.4 之后被替换为 failedAuthorization()