study-api-v2/app/Http/Middleware/AdminApiAuthenticate.php

99 lines
2.4 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Auth\AuthenticationException;
use App\Services\Auth\TokenAuthService;
use Illuminate\Support\Facades\Auth;
/**
* 后台API认证中间件
*
* 使用TokenAuthService进行认证支持缓存以减少数据库查询
* 在认证失败时返回JSON格式的401错误而不是重定向到登录页面
*/
class AdminApiAuthenticate
{
/**
* Token认证服务
*/
protected TokenAuthService $tokenAuthService;
/**
* 构造函数
*/
public function __construct(TokenAuthService $tokenAuthService)
{
$this->tokenAuthService = $tokenAuthService;
}
/**
* 处理传入的请求
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string ...$guards
* @return mixed
*/
public function handle(Request $request, Closure $next, ...$guards)
{
$guards = empty($guards) ? ['sanctum'] : $guards;
// 获取请求中的token
$token = $this->getTokenFromRequest($request);
if (!$token) {
return $this->unauthenticatedResponse();
}
// 使用TokenAuthService验证token并获取用户带缓存
$user = $this->tokenAuthService->validateTokenAndGetUser($token, $guards[0]);
if (!$user) {
return $this->unauthenticatedResponse();
}
// 设置当前认证用户
Auth::guard($guards[0])->setUser($user);
Auth::shouldUse($guards[0]);
return $next($request);
}
/**
* 从请求中获取token
*
* @param Request $request
* @return string|null
*/
protected function getTokenFromRequest(Request $request): ?string
{
// 从Authorization Header获取token
$header = $request->header('Authorization', '');
if (strpos($header, 'Bearer ') === 0) {
return substr($header, 7);
}
// 从URL参数获取token可选
return $request->query('token');
}
/**
* 返回未授权响应
*
* @return \Illuminate\Http\JsonResponse
*/
protected function unauthenticatedResponse()
{
return response()->json([
'success' => false,
'message' => '未授权访问,请先登录',
'code' => 401,
'data' => null
], 401);
}
}