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

如何为非基于用户的Laravel API实现授权?跨应用记账API权限保障

嘿,针对你的场景(两个独立Laravel应用调用Lumen记账API),我推荐以下几种成熟的授权方案,按实现复杂度从低到高排序,你可以根据自己的需求来选:

方案1:API密钥(API Key)认证

这是最直接、易实现的方案,非常适合服务间的简单授权场景。

实现步骤:

  • 第一步:为餐厅和书店应用分别生成唯一的API密钥(可以用Laravel的Str::random(60)生成),你可以把密钥存在Lumen的环境变量里,或者存入数据库的应用凭证表(如果需要动态管理多个客户端的话)。
  • 第二步:在Lumen中创建自定义中间件验证API密钥:
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class VerifyApiKey
{
    public function handle(Request $request, Closure $next): Response
    {
        $apiKey = $request->header('X-API-Key');
        
        // 这里可以根据实际情况验证:从环境变量取预设密钥,或者查数据库
        $validKeys = [
            env('RESTAURANT_APP_API_KEY'),
            env('BOOKSTORE_APP_API_KEY')
        ];
        
        if (!in_array($apiKey, $validKeys)) {
            return response()->json(['message' => 'Unauthorized'], Response::HTTP_UNAUTHORIZED);
        }
        
        // 可选:把当前请求的应用标识存入请求上下文,方便后续业务逻辑使用
        $request->attributes->set('app_type', $apiKey === env('RESTAURANT_APP_API_KEY') ? 'restaurant' : 'bookstore');
        
        return $next($request);
    }
}
  • 第三步:在Lumen的bootstrap/app.php中注册中间件:
$app->routeMiddleware([
    'api.key' => App\Http\Middleware\VerifyApiKey::class,
]);
  • 第四步:给需要保护的API路由分组,应用这个中间件:
$router->group(['middleware' => 'api.key'], function () use ($router) {
    $router->post('/transactions', 'TransactionController@store');
});
  • 第五步:在餐厅/书店的Laravel应用中,发起请求时携带API密钥:
// 餐厅应用发送交易请求示例
$response = Http::withHeaders([
    'X-API-Key' => env('LUMEN_API_KEY'),
])->post('https://your-lumen-api.com/transactions', [
    'amount' => 50.00,
    'description' => '售出汉堡套餐',
    // 其他交易数据
]);
方案2:HTTP Basic认证

如果不想自定义API密钥逻辑,HTTP Basic认证是另一种轻量的服务间授权选择。

实现步骤:

  • 第一步:在Lumen中创建自定义Basic认证中间件(也可以用框架自带的,但自定义更灵活适配你的多客户端场景):
<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class VerifyBasicAuth
{
    public function handle(Request $request, Closure $next): Response
    {
        $username = $request->getUser();
        $password = $request->getPassword();
        
        // 验证餐厅或书店的凭证
        $isRestaurantValid = ($username === env('RESTAURANT_APP_USER') && $password === env('RESTAURANT_APP_PASS'));
        $isBookstoreValid = ($username === env('BOOKSTORE_APP_USER') && $password === env('BOOKSTORE_APP_PASS'));
        
        if (!$isRestaurantValid && !$isBookstoreValid) {
            return response()->json(['message' => 'Unauthorized'], Response::HTTP_UNAUTHORIZED);
        }
        
        return $next($request);
    }
}
  • 第二步:在bootstrap/app.php中注册中间件,然后给路由分组应用该中间件(和方案1的路由配置逻辑一致)。
  • 第三步:Laravel应用中发起请求时携带Basic凭证:
$response = Http::withBasicAuth(env('LUMEN_API_USER'), env('LUMEN_API_PASS'))
    ->post('https://your-lumen-api.com/transactions', $transactionData);
方案3:Laravel Passport客户端凭证授权

因为你的两个应用都是Laravel生态,用Passport的客户端凭证授权是最契合的方案,安全性更高,还支持令牌过期、吊销等特性。

实现步骤:

  • 第一步:在Lumen中安装并配置Passport(注意Lumen需要手动复制Passport的配置文件到项目中),然后为餐厅和书店各创建一个客户端凭证(通过php artisan passport:client --client命令生成)。
  • 第二步:在Lumen的bootstrap/app.php中注册Passport的客户端中间件:
$app->routeMiddleware([
    'client' => Laravel\Passport\Http\Middleware\CheckClientCredentials::class,
]);
  • 第三步:保护API路由:
$router->group(['middleware' => 'client'], function () use ($router) {
    $router->post('/transactions', 'TransactionController@store');
});
  • 第四步:在餐厅/书店的Laravel应用中,先获取访问令牌再发起请求:
// 1. 获取客户端凭证令牌
$tokenResponse = Http::asForm()->post('https://your-lumen-api.com/oauth/token', [
    'grant_type' => 'client_credentials',
    'client_id' => env('PASSPORT_CLIENT_ID'),
    'client_secret' => env('PASSPORT_CLIENT_SECRET'),
    'scope' => '',
]);

$accessToken = $tokenResponse->json()['access_token'];

// 2. 发送交易请求
$response = Http::withHeaders([
    'Authorization' => 'Bearer ' . $accessToken,
])->post('https://your-lumen-api.com/transactions', $transactionData);
额外建议
  • 无论用哪种方案,一定要确保API使用HTTPS,避免凭证在传输过程中被窃取。
  • 可以在Lumen中添加日志记录,记录所有授权失败的请求,方便后续排查问题。
  • 如果需要区分请求来自餐厅还是书店,可以在授权验证通过后,把应用标识存入请求上下文,后续业务逻辑就能直接使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:33:53