You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中用Http-only Cookie+Axios访问受保护路由遇401问题

解决Laravel JWT Http-only Cookie认证401 Unauthorized问题

1. 修改JWT认证逻辑,从Http-only Cookie读取Token

默认的auth:api中间件只会从Authorization请求头解析JWT Token,不会自动读取Cookie。你需要自定义认证逻辑,让Laravel优先从auth_token Cookie中获取Token:

方法一:自定义JWT Guard

在app/Providers/AuthServiceProvider.php的boot方法中注册自定义Guard:

use Illuminate\Support\Facades\Auth;
use Tymon\JWTAuth\JWTGuard;

public function boot()
{
    $this->registerPolicies();

    Auth::extend('jwt-cookie', function ($app, $name, array $config) {
        $guard = new JWTGuard(
            $app['tymon.jwt'],
            Auth::createUserProvider($config['provider']),
            $app['request']
        );

        // 让Guard优先从Cookie获取Token, fallback到Bearer Token
        $guard->getJWTProvider()->setParser(function ($request) {
            return $request->cookie('auth_token') ?: $request->bearerToken();
        });

        $app->refresh('request', $guard, 'setRequest');

        return $guard;
    });
}

然后在config/auth.php中更新guards配置,替换默认的api驱动:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'jwt-cookie', // 使用自定义的guard驱动
        'provider' => 'users',
    ],
],

方法二:手动在中间件解析Cookie

如果不想自定义Guard,也可以在认证中间件中手动从Cookie取Token验证:

// 新建或修改app/Http/Middleware/AuthenticateWithCookie.php
use Closure;
use Tymon\JWTAuth\Facades\JWTAuth;
use Illuminate\Support\Facades\Auth;

class AuthenticateWithCookie
{
    public function handle($request, Closure $next)
    {
        try {
            $token = $request->cookie('auth_token');
            if (!$token) {
                throw new \Tymon\JWTAuth\Exceptions\TokenNotFoundException();
            }

            $user = JWTAuth::setToken($token)->authenticate();
            Auth::login($user);
        } catch (\Exception $e) {
            return response()->json(['message' => 'Unauthorized'], 401);
        }

        return $next($request);
    }
}

之后在路由或控制器中用这个中间件替换原来的auth:api。

2. 完善CORS全局配置

不要在登录响应中硬写CORS头,用Laravel CORS包做全局配置更可靠:

  • 确保config/cors.php配置正确:
return [
    'paths' => ['api/*', 'request.json', 'action.json'],
    'allowed_methods' => ['*'],
    'allowed_origins' => ['http://localhost:5173'],
    'allowed_headers' => ['Content-Type', 'X-Requested-With'],
    'supports_credentials' => true, // 必须开启,允许跨域携带Cookie
    'max_age' => 3600,
];
  • 确认app/Http/Kernel.php的api中间件组包含CORS处理中间件:
protected $middlewareGroups = [
    'api' => [
        \Fruitcake\Cors\HandleCors::class,
        'throttle:api',
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],
];

3. 检查Cookie参数配置

登录时设置的Cookie参数要符合跨域要求:

$cookie = Cookie::make(
    'auth_token',
    $token,
    60, // 有效期(分钟)
    '/', // 路径设为/,确保全站点路由都能访问到Cookie
    null, // 本地开发domain留空即可,生产环境填对应域名
    env('APP_ENV') !== 'local', // 生产环境开启HTTPS时设为true
    true, // 保持HttpOnly为true
    false,
    'Lax' // 跨域场景下如果Strict无效,可尝试改为Lax
);

4. 调试验证步骤

  • 打开浏览器开发者工具Network标签,检查请求的Request Headers中是否包含Cookie: auth_token=xxx,且Response Headers中Cookie的HttpOnly标记为true
  • 在受保护路由中临时打印dd($request->cookie('auth_token')),确认Laravel能获取到Cookie值
  • 用JWTAuth::setToken($token)->check()验证Token是否有效

内容的提问来源于stack exchange,提问作者bright-webb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 23:35:13