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

Laravel项目间Guzzle Digest认证失效,请求返回登录页

Laravel跨项目Guzzle请求认证页面返回登录页的解决方案

咱先捋清楚问题:你有两个Laravel项目,项目一有俩页面——一个得登录认证才能进,另一个随便访问。用项目二的Guzzle请求时,免认证页面正常,但要认证的那个只返回登录页。你当前的Guzzle代码是这样的:

<?php 
$client = new Client([ 
    'base_uri' => 'my_base_url', 
    'timeout' => 5.0, 
    'auth' => ['login', 'password', 'digest'], 
    'headers' => array(
        'Accept' => 'application/vnd.comay.v1.1+xml', 
        'Content-Type' => 'text/xml'
    ), 
]); 
$response = $client->get('/products/page2'); 
echo $response->getReasonPhrase(); 
$body = $response->getBody(); 
echo $body; 
?>

问题根源

Laravel默认的认证系统(不管是Breeze、Jetstream还是老UI)都是靠Session/Cookie维持登录状态的,但你现在用的auth参数是HTTP摘要认证,这和Laravel的Session认证完全不是一套逻辑!Guzzle发的请求里没有Laravel认的Session Cookie,系统自然判定你未登录,直接重定向到登录页了。

解决办法

临时方案:带Session Cookie请求

适合快速测试,步骤如下:

  1. 手动登录项目一,打开浏览器开发者工具(F12),在Application标签的Cookies里找到Laravel的Session Cookie(默认名叫laravel_session,具体看你项目一.env里的SESSION_COOKIE配置)
  2. 修改Guzzle配置,把这个Cookie加进去:
<?php 
$client = new Client([ 
    'base_uri' => 'my_base_url', 
    'timeout' => 5.0, 
    'headers' => array(
        'Accept' => 'application/vnd.comay.v1.1+xml', 
        'Content-Type' => 'text/xml',
        'Cookie' => 'laravel_session=你复制的cookie值' // 这里加Cookie
    ), 
]); 
$response = $client->get('/products/page2'); 
echo $response->getReasonPhrase(); 
$body = $response->getBody(); 
echo $body; 
?>

推荐方案:用API令牌认证(服务间调用更靠谱)

Session Cookie的方式不仅有效期有限,跨域名还容易出问题,服务间调用更适合用Laravel的API令牌:

  1. 在项目一安装Laravel Sanctum(轻量够用):
    composer require laravel/sanctum
    php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
    php artisan migrate
    
  2. 在项目一的User模型里添加HasApiTokens trait:
    use Laravel\Sanctum\HasApiTokens;
    
    class User extends Authenticatable
    {
        use HasApiTokens, HasFactory, Notifiable;
        // ... 其他代码
    }
    
  3. 给需要调用的用户生成API令牌(可以手动在tinker里生成,或者做个后台页面):
    php artisan tinker
    $user = User::where('email', 'login@example.com')->first();
    $token = $user->createToken('Project2Access')->plainTextToken;
    echo $token; // 复制这个令牌
    
  4. 修改Guzzle请求,带上Bearer令牌:
    <?php 
    $client = new Client([ 
        'base_uri' => 'my_base_url', 
        'timeout' => 5.0, 
        'headers' => array(
            'Accept' => 'application/vnd.comay.v1.1+xml', 
            'Content-Type' => 'text/xml',
            'Authorization' => 'Bearer 你复制的API令牌' // 这里加令牌
        ), 
    ]); 
    $response = $client->get('/products/page2'); 
    echo $response->getReasonPhrase(); 
    $body = $response->getBody(); 
    echo $body; 
    ?>
    
  5. 最后要确保项目一的路由使用api守卫,或者在路由里指定认证守卫:
    Route::get('/products/page2', [ProductController::class, 'page2'])->middleware('auth:sanctum');
    

注意事项

  • 用Session Cookie的话,要注意Cookie的有效期,要是Cookie过期了就得重新复制
  • 跨域名场景下,要确保项目一的SESSION_DOMAIN配置允许项目二的域名访问,或者用子域名共享Cookie
  • API令牌要妥善保管,别泄露,要是泄露了可以在项目一的personal_access_tokens表里删除对应的令牌

内容的提问来源于stack exchange,提问作者Alexandr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:47:18