如何本地化Laravel Sanctum的“未授权”错误提示信息?
解决Laravel Sanctum未授权提示本地化问题
问题分析
你修改app/Exceptions/Handler.php的register方法后,始终返回默认英文的未授权提示,核心原因是异常处理器执行时机早于会话中间件初始化:
- 若使用API路由,默认
api中间件组不包含StartSession,无法读取会话中存储的用户语言; - 即使是Web路由,异常回调执行时会话还未完成加载,导致无法获取
locale值。
解决方案
方案1:在异常回调中手动加载会话并设置语言
如果你的认证依赖会话(如Sanctum SPA模式),可在renderable回调中优先读取会话语言并设置:
public function register() { $this->reportable(function (Throwable $e) { // }); $this->renderable(function (AuthenticationException $e, $request) { // 尝试从会话获取用户设置的语言,不存在则用默认 if ($locale = $request->session()->get('locale')) { app()->setLocale($locale); } return response()->json([ 'status_code' => 401, 'success' => false, 'message' => __('auth.unauthenticated') ], 401); }); }
注意:需确保路由所在中间件组包含
StartSession和EncryptCookies(如web中间件组),否则会话无法访问。
方案2:通过请求头传递语言(推荐API场景)
API请求通常为无状态,建议让前端在请求头中携带语言标识(如X-Locale),后端直接从请求头读取:
public function register() { $this->reportable(function (Throwable $e) { // }); $this->renderable(function (AuthenticationException $e, $request) { // 优先取请求头语言, fallback到应用默认 $locale = $request->header('X-Locale', config('app.locale')); app()->setLocale($locale); return response()->json([ 'status_code' => 401, 'success' => false, 'message' => __('auth.unauthenticated') ], 401); }); }
前端请求示例(Axios):
axios.get('/api/xxx', { headers: { 'X-Locale': 'de' } })
方案3:全局中间件提前设置语言(一劳永逸)
创建全局中间件,在请求处理前统一设置语言,确保异常处理时已生效:
- 创建中间件
app/Http/Middleware/SetLocale.php:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; class SetLocale { public function handle(Request $request, Closure $next) { // 优先级:会话存储 > 请求头 > 应用默认 $locale = $request->session()->get('locale') ?? $request->header('X-Locale') ?? config('app.locale'); app()->setLocale($locale); return $next($request); } }
- 在
app/Http/Kernel.php中注册中间件:
- 若为Web路由,添加到
$middlewareGroups['web']数组; - 若为API路由,添加到
$middlewareGroups['api']数组:
protected $middlewareGroups = [ 'web' => [ // ... 其他中间件 \App\Http\Middleware\SetLocale::class, ], 'api' => [ // ... 其他中间件 \App\Http\Middleware\SetLocale::class, ], ];
- 简化
Handler.php代码:
public function register() { $this->reportable(function (Throwable $e) { // }); $this->renderable(function (AuthenticationException $e, $request) { return response()->json([ 'status_code' => 401, 'success' => false, 'message' => __('auth.unauthenticated') ], 401); }); }
内容的提问来源于stack exchange,提问作者Tamás H
相关产品推荐
相关产品推荐

