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

Laravel 5.8如何用Passport API认证实现Web中间件路由鉴权?

当然可行!Laravel的Guard机制就是为了灵活适配各种认证场景而生的,刚好能解决你这种用API凭证给web路由创建会话的需求。我给你梳理下具体怎么实现:

核心思路

你的app站点没有本地数据库,没法用默认的session guard直接查询用户数据,所以我们需要自定义一个Guard:让它通过调用core站点的API来验证用户凭证,验证通过后把用户信息存在app本地的会话里,这样web路由就能通过这个Guard识别用户的登录状态了。

具体实现步骤

1. 创建自定义Guard类

先在app/Auth目录下新建一个ApiSessionGuard.php文件(如果Auth目录不存在就手动创建)。这个类要实现Laravel的Guard接口,核心是处理用户获取、凭证验证、登录登出这些逻辑:

<?php

namespace App\Auth;

use Illuminate\Auth\GuardHelpers;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\Client\PendingRequest;
use Illuminate\Support\Facades\Http;

class ApiSessionGuard implements Guard
{
    use GuardHelpers;

    protected $request;

    public function __construct($request)
    {
        $this->request = $request;
    }

    // 获取当前登录用户:先从session取,取不到就返回null
    public function user()
    {
        if (!is_null($this->user)) {
            return $this->user;
        }

        $userData = $this->request->session()->get('api_user');
        if ($userData) {
            // 把session里的数组转成User模型(只是个数据容器)
            $this->user = new \App\User($userData);
            return $this->user;
        }

        return null;
    }

    // 验证用户凭证:调用core的登录API
    public function validate(array $credentials = [])
    {
        $response = $this->getApiClient()->post('/api/login', $credentials);

        if ($response->successful()) {
            $userData = $response->json()['user'];
            // 把用户信息存入session
            $this->request->session()->put('api_user', $userData);
            $this->user = new \App\User($userData);
            return true;
        }

        return false;
    }

    // 手动登录用户:比如拿到API返回的用户信息后直接创建会话
    public function login($user)
    {
        $this->request->session()->put('api_user', $user->toArray());
        $this->setUser($user);
    }

    // 登出用户:清除session,可选调用core的登出API销毁token
    public function logout()
    {
        $this->request->session()->forget('api_user');
        $this->user = null;
        $this->getApiClient()->post('/api/logout');
    }

    // 配置HTTP客户端,带上Passport客户端凭证
    protected function getApiClient(): PendingRequest
    {
        return Http::withHeaders([
            'Accept' => 'application/json',
        ])->withBasicAuth(
            config('services.core.client_id'),
            config('services.core.client_secret')
        )->baseUrl(config('services.core.url'));
    }
}

2. 配置Guard与Provider

修改config/auth.php,添加自定义的guard和对应的用户provider:

'guards' => [
    'web' => [
        'driver' => 'api_session', // 指定我们自定义的guard驱动
        'provider' => 'api_users',
    ],
    // 保留原来的api guard
    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],

'providers' => [
    'api_users' => [
        'driver' => 'eloquent',
        'model' => App\User::class,
    ],
],

3. 注册Guard驱动

在App\Providers\AppServiceProvider的boot方法里,注册我们自定义的Guard驱动:

use App\Auth\ApiSessionGuard;
use Illuminate\Support\Facades\Auth;

public function boot()
{
    Auth::extend('api_session', function ($app, $name, array $config) {
        return new ApiSessionGuard($app['request']);
    });
}

4. 调整App站点的User模型

因为App站点没有数据库,我们的User模型不需要继承Eloquent的Model,改成一个简单的数据容器即可:

<?php

namespace App;

class User
{
    protected $attributes = [];

    public function __construct(array $attributes = [])
    {
        $this->attributes = $attributes;
    }

    public function __get($key)
    {
        return $this->attributes[$key] ?? null;
    }

    public function toArray()
    {
        return $this->attributes;
    }

    // 实现Guard需要的身份标识方法
    public function getAuthIdentifier()
    {
        return $this->attributes['id'];
    }
}

5. 给Web路由添加认证中间件

现在你的web路由就可以直接使用auth:web中间件了,比如:

Route::middleware('auth:web')->group(function () {
    Route::get('/dashboard', function () {
        return view('dashboard', ['user' => auth()->user()]);
    });
});
一些注意事项
  • 确保App站点的session配置正常(比如用文件或Redis存储,不需要数据库)
  • 可以在自定义Guard里添加定期验证逻辑,比如每次请求时调用core的API检查用户会话是否有效
  • 如果core站点的用户信息更新了,App站点session里的信息不会自动同步,你可以在需要的时候重新调用API拉取并更新session

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 09:07:47