Laravel11有没有办法在不重写Authenticate中间件的情况下直接捕获AuthenticationException异常类?

我想实现类似下面的效果,捕获以后自定义响应。9/10版本的时候都是重写Authenticate全局中间件,11中有没有更简单的方式

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {

    })
    ->withExceptions(function (Exceptions $exceptions) {
        $exceptions->report(function (\Illuminate\Auth\AuthenticationException $e) {
            // 自定义处理
        })->stop();
    })->create();
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
nff93
最佳答案
return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {

    })
    ->withExceptions(function (Exceptions $exceptions) {
        $exceptions->render(function (\Illuminate\Auth\AuthenticationException $e) {
           return '这儿改为你实际要返回的数据即可,比如数组';
        });
    })->create();
1个月前 评论
勇敢的心 (楼主) 1个月前
nff93 (作者) 1个月前
nff93 (作者) 1个月前
讨论数量: 10

自己push一个全局的中间件捕获,类似这种
github.com/deatil/larke-admin/blob...

1个月前 评论

给你参考,再使用一下异常类接管

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->render(function (Throwable $e, Request $request)  {
        match (true) {
            $e instanceof AuthenticationException => throw new JsonResponseException($e->getMessage(), [], 401),
            $e instanceof UnauthorizedException => throw new JsonResponseException($e->getMessage(), [], 403),
            $e instanceof MethodNotAllowedHttpException => throw new JsonResponseException(
                'local' === $env ? $e->getMessage() : '请求的资源不存在或已被删除。',
                [],
                404
            ),
            $e instanceof NotFoundHttpException => throw new JsonResponseException(
                'local' === $env ? $e->getMessage() : '请求的资源不存在或已被删除。',
                [],
                404
            ),
            $e instanceof InvalidArgumentException => throw new JsonResponseException(
                'local' === $env ? $e->getMessage() : '传递的参数无效,请检查请求数据。',
                [],
                400
            ),
            default => throw new JsonResponseException(
                'local' === $env ? $e->getMessage() : '系统发生未知错误,请稍后再试或联系技术支持。'
            ),
        };
    });
})->create();
1个月前 评论
nff93
return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {

    })
    ->withExceptions(function (Exceptions $exceptions) {
        $exceptions->render(function (\Illuminate\Auth\AuthenticationException $e) {
           return '这儿改为你实际要返回的数据即可,比如数组';
        });
    })->create();
1个月前 评论
勇敢的心 (楼主) 1个月前
nff93 (作者) 1个月前
nff93 (作者) 1个月前

我是在 handler.php处理的,这是 laravel10 的处理方式,laravel11 项目不清楚。

        // 登录过期
        if (str_starts_with($request->path(), 'api') && $e instanceof AuthenticationException) {
            return response()->json([
                'status'  => 'AuthenticationException',
                'code'    => HttpStatusEnum::UNAUTHENTICATED->value,
                'error_code' => HttpStatusEnum::UNAUTHENTICATED->value,
                'message' => HttpStatusEnum::UNAUTHENTICATED->msg(),
            ]);
        }
1个月前 评论
ononl (作者) 1个月前
    ->withExceptions(function (Exceptions $exceptions) {
        (new \App\Exceptions\Handler($exceptions))->handle();
    })->create();

自定义一个 handler 然后处理

<?php

namespace App\Exceptions;


use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Throwable;

class Handler
{


    /**
     * A list of the inputs that are never flashed for validation exceptions.
     *认证异常时不被flashed的数据
     * @var array
     */
    protected $dontFlash = [
        'current_password',
        'password',
        'password_confirmation',
    ];

    public function __construct(public Exceptions $excepHandler){
    }

    public function handle(){

        $this->excepHandler->dontFlash($this->dontFlash);
        // 异常处理
        $this->excepHandler->render(function (Throwable $e){
            if($e instanceof \Illuminate\Auth\AuthenticationException){
                $return = [
                    'code' => 403,
                    'msg'  => 'Token 已失效'
                ];
                return response()->json($return,403);
            }
        });
    }
}
1个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!