Laravel 护照 API return 异常 HTML 而不是 JSON 响应
Laravel passport API return Exception as HTML instead of JSON response
我的 API 是用 Laravel 5.4 Passport 构建的,授权和颁发访问令牌工作正常,但是当使用 Insomnia 或 Postman 处理如下资源时:
Authorization: Bearer [encrypted access token goes here which has only "manage-users" scope]
Content-Type: application/json
Accept: application/json
我将上述请求发送给此 url:
已限制访问具有此范围的令牌的此资源
manage-users, test-scope-1
Route::get('/users', [
'as' => 'users',
'uses' => 'UsersController@index'
])->middleware(['auth:api', 'scopes:manage-users,test-scope-1']);
范围已定义在:
AuthServiceProvider
Passport::tokensCan([
'manage-users' => 'testing',
'test-scope-1' => 'test scope',
'test-scope-2' => 'another test scope',
]);
protected $routeMiddleware = [
...,
...,
...,
'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class
];
用于授权此请求的令牌仅具有 "manage-users" 范围,因此除了访问此资源所需的范围 "test-scope-1".
虽然我得到了一个 HttpException "Invalid scope(s) provided." 因为 HTML 响应不是 json
编辑
Auth-Scaffolding is not installed.
经过大量挖掘,我找到了一种在异常处理程序中解决问题的方法,如下所示:
public function render($request, Exception $exception)
{
// If the request wants JSON (AJAX doesn't always want JSON)
if ($request->wantsJson()) {
if($exception instanceof MissingScopeException){
// Define the response
$response = [
'errors' => 'Sorry, something went wrong.'
];
// If the app is in debug mode
if (config('app.debug')) {
// Add the exception class name, message and stack trace to response
//$response['exception'] = get_class($exception); // Reflection might be better here
$response['message'] = $exception->getMessage();
//$response['trace'] = $exception->getTrace();
}
// Default response of 401
$status = 403;//forbidden
// If this exception is an instance of HttpException
if ($this->isHttpException($exception)) {
// Grab the HTTP status code from the Exception
$status = $exception->getStatusCode();
}
// Return a JSON response with the response array and status code
return response()->json($response, $status);
}
}
return parent::render($request, $exception);
}
这样我就能及早发现错误并return一个json对象作为响应。
我的 API 是用 Laravel 5.4 Passport 构建的,授权和颁发访问令牌工作正常,但是当使用 Insomnia 或 Postman 处理如下资源时:
Authorization: Bearer [encrypted access token goes here which has only "manage-users" scope]
Content-Type: application/json
Accept: application/json
我将上述请求发送给此 url:
已限制访问具有此范围的令牌的此资源
manage-users, test-scope-1
Route::get('/users', [
'as' => 'users',
'uses' => 'UsersController@index'
])->middleware(['auth:api', 'scopes:manage-users,test-scope-1']);
范围已定义在:
AuthServiceProvider
Passport::tokensCan([
'manage-users' => 'testing',
'test-scope-1' => 'test scope',
'test-scope-2' => 'another test scope',
]);
protected $routeMiddleware = [
...,
...,
...,
'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class
];
用于授权此请求的令牌仅具有 "manage-users" 范围,因此除了访问此资源所需的范围 "test-scope-1".
虽然我得到了一个 HttpException "Invalid scope(s) provided." 因为 HTML 响应不是 json
编辑
Auth-Scaffolding is not installed.
经过大量挖掘,我找到了一种在异常处理程序中解决问题的方法,如下所示:
public function render($request, Exception $exception)
{
// If the request wants JSON (AJAX doesn't always want JSON)
if ($request->wantsJson()) {
if($exception instanceof MissingScopeException){
// Define the response
$response = [
'errors' => 'Sorry, something went wrong.'
];
// If the app is in debug mode
if (config('app.debug')) {
// Add the exception class name, message and stack trace to response
//$response['exception'] = get_class($exception); // Reflection might be better here
$response['message'] = $exception->getMessage();
//$response['trace'] = $exception->getTrace();
}
// Default response of 401
$status = 403;//forbidden
// If this exception is an instance of HttpException
if ($this->isHttpException($exception)) {
// Grab the HTTP status code from the Exception
$status = $exception->getStatusCode();
}
// Return a JSON response with the response array and status code
return response()->json($response, $status);
}
}
return parent::render($request, $exception);
}
这样我就能及早发现错误并return一个json对象作为响应。