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

Laravel跨应用API登录问题求助:POS系统无法登录库存系统

问题分析与解决方案

问题根源

  1. 跨应用会话不共享:Laravel默认每个应用的Session独立存储,POS通过Http客户端调用库存API时,auth()->login($user)仅在API请求的临时会话中生效,无法同步到用户浏览器的库存系统会话。
  2. 重定向无效:API返回的redirect('/dashboard')被POS的Http客户端接收,但无法将库存系统的会话Cookie写入用户浏览器,导致用户直接访问库存页面时无有效会话,被重定向到登录页。

解决方案

方案一:共享Session(适合同/子域名场景)

通过配置两个应用共享Session存储,让用户在POS登录的会话能同步到库存系统。

1. 统一Session配置

在两个应用的.env文件中设置相同的Session参数:

SESSION_DRIVER=redis
SESSION_DOMAIN=.yourdomain.com # 例如pos.yourdomain.com和inventory.yourdomain.com共享根域名
SESSION_LIFETIME=120
APP_KEY=相同的APP_KEY值 # 两个应用必须使用相同的APP_KEY

确保两个应用连接到同一个Redis实例,Redis配置一致。

2. 修改POS跳转逻辑

替换POS控制器的inventoryLogin方法,生成带签名的跳转链接,直接引导用户浏览器到库存系统的验证路由:

public function inventoryLogin()
{
    $payload = [
        'email' => auth()->user()->email,
        'role' => auth()->user()->role,
        'timestamp' => time(),
    ];
    // 生成签名防止请求篡改
    $signature = hash_hmac('sha256', http_build_query($payload), config('app.key'));
    $payload['signature'] = $signature;

    return redirect()->to('http://inventory.sys/login/verify-pos?' . http_build_query($payload));
}

3. 库存系统添加验证路由

在库存系统的web.php中添加路由(不要放在api.php,需要处理浏览器会话):

Route::get('login/verify-pos', function(Request $request) {
    $rules = [
        'email' => 'email|required|max:300',
        'role' => 'required|max:300',
        'timestamp' => 'required|integer|max:' . (time() + 300), // 限制5分钟内有效
        'signature' => 'required',
    ];

    $validator = Validator::make($request->all(), $rules);
    if ($validator->fails()) {
        return redirect('/login')->withErrors($validator);
    }

    // 验证签名合法性
    $payload = $request->only(['email', 'role', 'timestamp']);
    $expectedSignature = hash_hmac('sha256', http_build_query($payload), config('app.key'));
    if (!hash_equals($expectedSignature, $request->signature)) {
        return redirect('/login')->withErrors(['message' => '无效的请求签名']);
    }

    if ($request->role !== "Administrator") {
        return redirect('/login')->withErrors(['message' => '无权限访问']);
    }

    $user = User::where('email', $request->email)->firstOrFail();
    auth()->login($user);

    return redirect('/dashboard');
});

方案二:JWT/Passport单点登录(适合跨域名场景)

通过Laravel Passport实现OAuth2认证,POS获取库存系统的令牌后,引导用户到库存系统验证令牌并登录。

1. 库存系统配置Passport

安装并配置Laravel Passport,创建密码授权客户端,记录client_id和client_secret。

2. POS获取令牌并跳转

修改POS控制器的inventoryLogin方法:

public function inventoryLogin()
{
    $response = Http::asForm()->post('http://inventory.sys/oauth/token', [
        'grant_type' => 'password',
        'client_id' => config('services.inventory.client_id'),
        'client_secret' => config('services.inventory.client_secret'),
        'username' => auth()->user()->email,
        'password' => auth()->user()->password, // 确保两个应用密码加密方式一致
        'scope' => '',
    ]);

    if ($response->successful()) {
        $token = $response->json()['access_token'];
        return redirect()->to('http://inventory.sys/login/verify-jwt?token=' . $token);
    }

    return redirect()->back()->withErrors(['message' => '登录库存系统失败']);
}

3. 库存系统验证令牌并登录

在库存系统的web.php中添加路由:

Route::get('login/verify-jwt', function(Request $request) {
    $token = $request->get('token');
    if (!$token) {
        return redirect('/login')->withErrors(['message' => '缺少登录令牌']);
    }

    try {
        $user = auth()->guard('api')->setToken($token)->user();
        if (!$user || $user->role !== "Administrator") {
            throw new Exception('无权限访问');
        }

        auth()->login($user);
        return redirect('/dashboard');
    } catch (Exception $e) {
        return redirect('/login')->withErrors(['message' => $e->getMessage()]);
    }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:57:40