讲师中心 微信公众号
AI工具推荐 视频效率加速

PHP开发GraphQL API完整教程(含Laravel Sanctum)

浅明姑娘_3275

浅明姑娘_3275

发布时间:2026-05-14 22:13:35

|

947人浏览过

|

来源于php中文网

原创

结论:Laravel + rebing/graphql-laravel 可行,但需手动调用 Sanctum::authenticate() 并在 context 中显式注入 user,否则 @can、$context->user 均失效;GraphQL 不走路由中间件,Auth 状态丢失。

php开发graphql api完整教程(含laravel sanctum)

直接说结论:用 Laravel + rebing/graphql-laravel 搭 GraphQL API 是可行的,但和 Sanctum 集成时,Sanctum::authenticate() 不会自动触发,必须手动调用;否则所有 @can 或 $context->user 都是 null。

GraphQL 请求不走 Laravel 中间件,Auth 状态丢失

Laravel 的 Sanctum 中间件(如 auth:sanctum)只对 HTTP 路由生效,而 rebing/graphql-laravel 默认把整个 GraphQL 请求当作一个 POST 到 /graphql,内部用 GraphQLController 处理,绕过了路由级中间件链。

结果就是:Auth::user() 始终为 null,即使请求头带了 Authorization: Bearer xxx 或已设置 Sanctum Cookie。

解决方法是手动在 GraphQL 查询/变更前注入认证逻辑:

立即学习“PHP免费学习笔记(深入)”;

  • 在 config/graphql.php 的 'schema' => ['query' => [...]] 之前,加一个全局 middleware 数组,但该包不支持传统中间件写法
  • 更可靠的做法:在每个需要鉴权的 Query 或 Mutation 类的 resolve() 方法开头,显式调用 Sanctum::authenticate($request)
  • 或者统一在 GraphQLController@query 中提前执行(需重写控制器或监听 GraphQLQueryExecuted 事件)

推荐后者——在 app/Http/Controllers/GraphQLController.php 中重写 query():

public function query(Request $request)
{
    // 手动触发 Sanctum 认证,确保 $request->user() 可用
    if ($request->hasHeader('Authorization') || $request->hasCookie('laravel_session')) {
        Sanctum::authenticate($request);
    }
    return parent::query($request);
}

rebing/graphql-laravel 的 context 不自动包含 user

即便 $request->user() 已存在,rebing/graphql-laravel 默认也不会把它塞进 GraphQL 的 $context。这意味着你在 resolver 里写 $context->user 会报错或返回空。

必须在 config/graphql.php 中显式配置 'context' => function (Request $request) { ... }:

Laravel Creem Agent
Laravel Creem Agent

Creem 支付商店助理 — 查询订阅、客户、交易、产品,执行心跳检查,管理本地 Laravel支付商店。

下载
'context' => function (Request $request) {
    // 确保 Sanctum 已运行
    if (! $request->user() && $request->hasHeader('Authorization')) {
        Sanctum::authenticate($request);
    }
    return ['user' => $request->user()];
},

注意:这个闭包只在每次请求开始时运行一次,所以要在这里完成所有上下文初始化,比如 DB::connection() 切换、租户识别等也得放这儿。

使用 @can 指令时权限检查总失败

rebing/graphql-laravel 提供的 @can 指令依赖 Illuminate\Auth\Access\Gate,但它默认从 Auth::user() 取用户——而你刚知道,这个值在 GraphQL 上下文中并不自动可用。

常见错误现象:"Unauthenticated." 或 "This action is unauthorized." 即使 token 正确、用户已登录。

根本原因不是策略写错了,而是 @can 指令没拿到 user 实例。修复方式有两个:

  • 在 context 配置中确保 'user' 键存在且非 null(见上一节)
  • 重写 @can 指令的解析逻辑,在 app/GraphQL/Directives/CanDirective.php 中覆盖 resolveField,从 $context['user'] 而非 Auth::user() 获取主体
  • 更轻量的做法:不用 @can 指令,改在 resolver 内部用 $context['user']->can('edit post') 显式判断,可控性更强

Sanctum Token 过期时间与 GraphQL 长连接场景不匹配

Sanctum 默认 token 是长期有效的(除非手动 token()->delete()),但这对 GraphQL 客户端(尤其是移动端或桌面端)容易造成“静默失效”:用户长时间未操作,token 其实还活着,但 session cookie 可能已被浏览器清理,导致后续请求因 Cookie 缺失而认证失败。

这不是 GraphQL 特有,但 GraphQL 更容易暴露这个问题——因为前端往往复用同一个 client 实例,不会像页面跳转那样自然触发重新登录流程。

建议动作:

  • 前端在收到 401 响应后,主动清空本地 token 并跳转登录页(不要只弹提示)
  • 后端在 GraphQL resolver 中检测 !$context['user'] 时,统一返回自定义错误码(如 UNAUTHENTICATED),避免混用 500 或泛化 message
  • 如果用 Cookie 模式,确保 SESSION_DRIVER=cookie 且 sanctum.stateful 配置包含你的前端域名

真正麻烦的不是怎么配通,而是当 $context['user'] 在某个 resolver 里突然为 null,而你忘了它其实取决于前面那个 Sanctum::authenticate() 是否被调用过——这个点很容易漏在调试时只看策略、不查认证链路。

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

10244

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

6041

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

2095

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

3788

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

4494

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

3531

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

5037

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

3942

2023.11.13

FrankenPHP集成Laravel详细教程
FrankenPHP集成Laravel详细教程

本专题提供FrankenPHP集成Laravel的详细配置指南,全面解析运行原理、开发环境搭建、Caddyfile配置、Octane工作模式、数据库连接、队列任务、定时任务和生产环境优化,解决部署过程中常见的报错与兼容性问题。

40

2026.10.08

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
墨刀帮助中心
墨刀帮助中心

共0课时 | 0人学习

MyEclipse学习中心
MyEclipse学习中心

共0课时 | 0人学习

Apache Subversion 官方手册
Apache Subversion 官方手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn