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

Laravel中如何使用API返回的响应密钥作为中间件实现路由鉴权

全路由API令牌鉴权实现方案

你之前用中间件做登录态校验的思路完全可以复用,只是把本地session校验逻辑替换为API令牌校验即可,具体实现分4步:

1. 改造登录流程,安全存储返回令牌

你当前的Basic Auth登录请求逻辑不需要改,拿到接口响应后先解析出返回的鉴权令牌,用安全的方式存储:

  • 优先用httpOnly属性的Cookie存储令牌,禁止前端JS直接读取,避免XSS攻击窃取;同时开启secure(HTTPS环境)、SameSite=Strict属性防止CSRF风险
  • 不要把令牌存在localStorage、sessionStorage这类可被JS读取的存储中

PHP示例代码:

// 解析登录接口返回结果,字段名替换成你接口实际返回的字段即可
$responseData = json_decode($response->getBody()->getContents(), true);
$authToken = $responseData['access_token'];
$expireTs = time() + $responseData['expires_in']; // 接口一般会返回令牌有效时长,单位为秒

// 写入安全Cookie
setcookie(
    name: 'api_auth_token',
    value: $authToken,
    expire: $expireTs,
    path: '/',
    secure: true,
    httponly: true,
    samesite: 'Strict'
);

2. 开发全局鉴权中间件

中间件逻辑分三层,和你之前做本地登录校验的流程基本一致:

  • 先配置白名单:登录页、登录提交接口、公开访问的静态资源、回调地址等不需要鉴权的路径直接放行,避免重定向死循环
  • 校验请求携带的Cookie中是否存在有效令牌,不存在直接重定向到登录页
  • 携带令牌请求后端API的令牌校验接口(一般是/me、/token/check这类校验端点,按你后端API实际提供的地址配置):
    • 接口返回200状态码代表令牌有效,把接口返回的用户信息挂载到请求对象上,放行请求到对应业务路由
    • 接口返回401/403状态码代表令牌过期、伪造或被吊销,清除本地无效Cookie,重定向到登录页
    • 接口请求超时或服务异常时,返回503兜底提示页

以PHP PSR规范中间件为例(适配Laravel、Slim、Hyperf等主流PHP框架):

<?php
namespace App\Http\Middleware;

use GuzzleHttp\Client;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as Handler;
use Psr\Http\Message\ResponseInterface as Response;

class ApiAuthMiddleware
{
    public function process(Request $request, Handler $handler): Response
    {
        // 白名单路由直接放行
        $currentPath = $request->getUri()->getPath();
        $publicPaths = ['/login', '/api/sign-in', '/favicon.ico'];
        if (in_array($currentPath, $publicPaths)) {
            return $handler->handle($request);
        }

        // 检查Cookie中是否存在令牌
        $token = $request->getCookieParams()['api_auth_token'] ?? '';
        if (empty($token)) {
            return new \GuzzleHttp\Psr7\Response(302, ['Location' => '/login']);
        }

        // 请求后端API校验令牌有效性
        try {
            $client = new Client();
            $checkResp = $client->get('你的API令牌校验地址', [
                'headers' => [
                    // 令牌前缀按后端API要求调整,多数场景为Bearer
                    'Authorization' => 'Bearer ' . $token,
                    'Accept' => 'application/json'
                ],
                'timeout' => 3
            ]);
            // 校验通过,写入用户信息到请求属性,后续业务可直接调用
            $user = json_decode($checkResp->getBody()->getContents(), true);
            $request = $request->withAttribute('current_user', $user);
            return $handler->handle($request);
        } catch (\GuzzleHttp\Exception\ClientException $e) {
            // 令牌无效,清除过期Cookie跳登录
            setcookie('api_auth_token', '', time() - 3600, '/');
            return new \GuzzleHttp\Psr7\Response(302, ['Location' => '/login?code=invalid_token']);
        } catch (\Exception $e) {
            // 鉴权服务异常兜底
            return new \GuzzleHttp\Psr7\Response(503, [], '服务暂时不可用,请稍后重试');
        }
    }
}

3. 注册中间件为全局路由中间件

把写好的鉴权中间件注册到框架的全局中间件栈中,默认覆盖所有Web路由,不需要单独给路由分组加鉴权注解,避免后续新增路由漏加鉴权导致未授权访问。

如果你用的是React/Vue这类纯前端SPA应用,逻辑完全一致:把服务端中间件替换成前端路由守卫,令牌同样存在httpOnly Cookie中,路由跳转前调用校验接口判断是否放行即可,所有API请求统一配置携带Cookie。

4. 业务请求统一附带令牌

后续所有业务逻辑调用后端API时,直接从Cookie中读取存储的令牌,放到请求的Authorization头中传给后端即可,不需要在每个业务接口重复做登录态校验。如果后端API提供了令牌刷新接口,可以在中间件校验时判断令牌剩余有效期,临近过期时自动调用刷新接口更新Cookie中的令牌,避免用户频繁掉线。

额外优化点

  • 静态资源(JS/CSS/图片等)可以直接在Nginx/Apache层面配置放行,不需要走中间件鉴权逻辑,减少不必要的API请求,提升响应速度
  • 可以在中间件层做短时间的本地缓存(比如1分钟Redis缓存),把令牌和对应的用户信息做映射,避免每个请求都调用后端校验接口,降低后端API压力
  • 登出逻辑直接清除本地存储的Cookie,同时调用后端API的令牌吊销接口即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 08:48:31