Php 如何在Laravel 5.2中以JSON格式返回403响应?
我正在尝试用Laravel5.2开发一个RESTful API。我不知道如何以JSON格式返回失败的授权。目前,它抛出的是403页错误,而不是JSON 控制器:Php 如何在Laravel 5.2中以JSON格式返回403响应?,php,laravel-5,laravel-5.2,Php,Laravel 5,Laravel 5.2,我正在尝试用Laravel5.2开发一个RESTful API。我不知道如何以JSON格式返回失败的授权。目前,它抛出的是403页错误,而不是JSON 控制器:TenantController.php class TenantController extends Controller { public function show($id) { $tenant = Tenant::find($id); if($tenant == null) retu
TenantController.php
class TenantController extends Controller
{
public function show($id)
{
$tenant = Tenant::find($id);
if($tenant == null) return response()->json(['error' => "Invalid tenant ID."],400);
$this->authorize('show',$tenant);
return $tenant;
}
}
class TenantPolicy
{
use HandlesAuthorization;
public function show(User $user, Tenant $tenant)
{
$users = $tenant->users();
return $tenant->users->contains($user->id);
}
}
'api.can' => \App\Http\Middleware\ApiAuthorization::class,
策略:TenantPolicy.php
class TenantController extends Controller
{
public function show($id)
{
$tenant = Tenant::find($id);
if($tenant == null) return response()->json(['error' => "Invalid tenant ID."],400);
$this->authorize('show',$tenant);
return $tenant;
}
}
class TenantPolicy
{
use HandlesAuthorization;
public function show(User $user, Tenant $tenant)
{
$users = $tenant->users();
return $tenant->users->contains($user->id);
}
}
'api.can' => \App\Http\Middleware\ApiAuthorization::class,
授权目前工作正常,但它显示403禁止页面,而不是返回json错误。是否可以将其作为403的JSON返回?并且,是否可以使其对所有失败的授权(不仅仅是在该控制器中)进行全局化?是的,在您的策略中使用一个简单的before方法,该方法将在所有其他授权检查之前执行
public function before($user, $ability,Request $request)
{
if (!yourconditiontrue) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return abort('403');
}
}
}
我们通过修改
App\exceptions\handler.php
中的异常处理程序,将其添加到render
函数中,成功地解决了这个问题
public function render($request, Exception $e)
{
if ($e instanceof AuthorizationException)
{
return response()->json(['error' => 'Not authorized.'],403);
}
return parent::render($request, $e);
}
您可以拦截异常
try {
$this->authorize('update', $data);
} catch (\Exception $e)
{
return response()->json(null, 403);
}
至于Laravel的最新版本,从现在的7.x版开始 通常,设置请求头'Accept'=>'application/json'会告诉Laravel您希望返回json响应
对于错误,您还需要通过在.env文件上设置APP_DEBUG=false来关闭调试,这将确保响应是json并且没有提供stacktrace。接受的答案有效,但是如果您不想为每个路由返回json,您可以使用中间件来处理 简要概述如何做到这一点: 创建一个
ApiAuthorization
类并扩展主auth类
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Auth\Middleware\Authorize;
use Illuminate\Auth\Access\AuthorizationException;
class ApiAuthorization extends Authorize
{
public function handle($request, Closure $next, $ability, ...$models)
{
try {
$this->auth->authenticate();
$this->gate->authorize($ability, $this->getGateArguments($request, $models));
} catch (AuthorizationException $e) {
return response()->json(['error' => 'Not authorized.'],403);
}
return $next($request);
}
}
更新你的路线。现在,您可以通过调用api来使用新的api验证中间件
此方法允许您在不修改全局异常处理程序的情况下返回特定路由的json。我在Laravel 7.3版中也遇到了同样的问题,其中未捕获AuthorizationException。我所知道的是,我们必须在Handler.php中包含AuthorizationException,就像
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Auth\Access\AuthorizationException;
use Throwable;
use Exception;
use Request;
use Response;
class Handler extends ExceptionHandler
{
// ...
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Throwable $exception
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws \Throwable
*/
public function render($request, Throwable $exception)
{
if ($exception instanceof AuthorizationException)
{
return response()->json(['message' => 'Forbidden'], 403);
}
if ($exception instanceof ModelNotFoundException && $request->wantsJson()) {
return response()->json(['message' => 'resource not found')], 404);
}
return parent::render($request, $exception);
}
// ...
}
Akram,在TenantPolicy.php
中,它将有一些函数,例如update
和store
,并且它将有不同的条件语句。那么,我应该在yourconditiontrue
中添加什么呢?无论您的授权逻辑是如何返回true-false的,如果是这样,那么您必须对每个函数执行条件,让我更新一下关于Laravel策略的知识,并在晚上返回一个解决方案,我将使用第三方库,如dingo/api。它为您处理了这个问题,以及版本控制和转换器。这在Laravel 5.4dd($e instaceof AuthorizationException)
中不起作用。它仍然有效。您的异常是否真的是AuthorizationException的实例?也许您忘记了使用“use”操作符导入AuthorizationException类?更准确地说,是catch\illumb\Auth\Access\AuthorizationException
。