CaiWuXiTong/app/Http/Middleware/AuthenticateOnceWithOAuth.php
15061959991 1adf627c0d feat: 财务系统二次开发 - 营销账户账单功能
- 基础环境:Docker 部署配置,源码挂载实时同步
- 修复:super_admin 权限补全、登录重定向循环
- 开发:店铺营销账户账单 - 抖音账户(15字段汇总账单)
- 开发:店铺营销账户账单 - 淘系支付宝账户(8字段流水账单)
- 开发:店铺营销账户账单 - 拼多多账户(7字段流水账单)
- 业务页面导航集成:config/business_navigation.php + Business\Pages 控制器
- 各平台独立表结构和视图,互不影响
2026-07-21 18:43:52 +08:00

108 lines
3.5 KiB
PHP

<?php
namespace App\Http\Middleware;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
class AuthenticateOnceWithOAuth
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, $next)
{
// Skip if OAuth module is disabled to avoid unnecessary processing
if (! config('oauth.enabled', false)) {
return $next($request);
}
$this->restoreAuthorizationHeaderIfMissing($request);
$guard = config('oauth.guards.api', 'passport');
$shouldLog = (bool) config('oauth.verbose_log', false) || ! app()->environment('production');
if ($shouldLog) {
// Keep verbose diagnostics outside production only.
Log::debug('OAuth: Attempting authentication', [
'method' => $request->method(),
'path' => $request->path(),
'has_bearer' => $request->bearerToken() ? 'yes' : 'no',
'has_authorization_header' => $request->headers->has('Authorization') ? 'yes' : 'no',
'guard' => $guard,
]);
}
// Check if user is authenticated via Passport
if (! Auth::guard($guard)->check()) {
if ($shouldLog) {
Log::warning('OAuth: Authentication failed', [
'guard' => $guard,
'ip' => $request->ip(),
'user_agent' => $request->userAgent(),
]);
}
return response()->json([
'message' => 'Unauthenticated.',
'error' => 'invalid_token',
'error_description' => 'The access token provided is expired, revoked, malformed, or invalid.',
], 401);
}
// Fire authenticated event with passport protocol
if ($user = Auth::guard($guard)->user()) {
if ($shouldLog) {
Log::debug('OAuth: Authentication successful', [
'user_id' => $user->id,
]);
}
// Set the user on the default guard so that the user() helper
// and middleware like IdentifyCompany (which calls auth()->user())
// can resolve the authenticated user without starting a session.
Auth::setUser($user);
}
return $next($request);
}
/**
* Restore Authorization header from common proxy server variables.
*
* Some reverse proxies do not pass the Authorization header directly,
* but expose it via alternate server variables.
*
* @param \Illuminate\Http\Request $request
* @return void
*/
protected function restoreAuthorizationHeaderIfMissing($request): void
{
if (! empty($request->header('Authorization'))) {
return;
}
$candidates = [
$request->server('HTTP_AUTHORIZATION'),
$request->server('REDIRECT_HTTP_AUTHORIZATION'),
$request->server('HTTP_X_FORWARDED_AUTHORIZATION'),
$request->header('X-Forwarded-Authorization'),
$request->header('X-Original-Authorization'),
];
foreach ($candidates as $candidate) {
if (! is_string($candidate) || trim($candidate) === '') {
continue;
}
$request->headers->set('Authorization', $candidate);
return;
}
}
}