### [瓜奇(GUAQI)框架彩虹聚合登录插件 —— 安装教程与完整介绍](https://8maoku.com/article/3522) **Published:** 2026-10-13T13:10:57 **Author:** zenghe **Excerpt:** 这个插件干三件事: 1. 用**彩虹聚合登录**替掉瓜奇框架里 QQ、微信、微博三路「直连各平台开放平台」的登… 这个插件干三件事: 1\. 用\*\*彩虹聚合登录\*\*替掉瓜奇框架里 QQ、微信、微博三路「直连各平台开放平台」的登录驱动; 2\. 顺手补掉瓜奇自身的两处硬编码限制 —— 微信登录方式被写死成 \`qr\`(导致报「AppID 参数错误」)、GraphQL 枚举里没有 \`weibo\`(导致微博点下去 403); 3\. 装完之后不新增任何前端 UI、不改动瓜奇任何一个文件,\*\*站点上原有的登录按钮保持原样\*\*,只是底层换了通道。 适用对象只有一个:\*\*跑瓜奇框架的 WordPress 站点\*\*。普通 WordPress 站点装它没有意义。 装完能立刻自查:后台有「运行时接管诊断」面板,还能匿名读一个 REST 接口,直接告诉你驱动槽位有没有抢到、枚举有没有注册上、微信模式改写有没有生效。不用靠点登录按钮猜。 — \## 一、为什么要做这个 瓜奇框架本身的社交登录是走 Overtrue Socialite 直连各平台开放平台的。这条路能走通,但有几个绕不开的事: \### 1. 每个平台都要单独申请、单独审核 – \*\*QQ\*\*:要开通 QQ 互联开发者、提交应用、等审核,回调域名还得备案一致; – \*\*微信\*\*:网站应用扫码登录要开微信开放平台,\*\*要企业主体认证,还要交 300 元/年\*\*,审核通过才能拿到 \`AppID\`; – \*\*微博\*\*:要走微博开放平台,同样有审核门槛。 三个平台三套流程,任何一套卡住,那个按钮就是死的。 \### 2. 微信这一路在瓜奇里被写死了 瓜奇后端对微信是这么算登录方式的(\`GraphQL/Querys/Utils/Social.php\`): “\`php $mode = $official ? ‘official’ : ($provider === ‘wechat’ ? ‘qr’ : ‘redirect’); “\` 意思是:微信一律返回 \`mode = “qr”\`。而前端对 \`qr\` 的处理是「\*\*忽略后端算好的授权地址,改加载微信官方 wxLogin.js,用返回的 clientId 当微信开放平台 appid 去渲染二维码\*\*」。 问题就在这:一旦你用聚合登录,那个 \`clientId\` 是\*\*聚合系统的应用号\*\*(线上实测是 \`1263\`),根本不是微信开放平台的 appid。前端拿它去调微信 SDK,微信那边直接回你: “\` AppID 参数错误 “\` \*\*这个报错跟你彩虹服务端配得对不对没关系,是前端把 appid 用错了地方。\*\* \### 3. 微博压根不在枚举里 瓜奇的 GraphQL 枚举 \`gqSocialProvider\` 只有这 7 个取值: “\` GITHUB FACEBOOK GOOGLE TWITTER TOUTIAO WECHAT QQ “\` 但「注册设置 → 社交登录」的条目是\*\*可以自由增删\*\*的。你一旦加了 \`weibo\`,前端会老老实实渲染出微博按钮,点下去必然撞上: “\` Value “WEIBO” does not exist in “GqSocialProvider” enum “\` 也就是经典的「按钮看得见、点不动」。 — \## 二、插件怎么解 思路很简单:\*\*只在框架的性格缺陷上打补丁,别的地方一概不碰。\*\* | 场景 | 瓜奇原生行为 | 本插件做法 | | ——————————- | ————————————————- | ——————————————————————– | | QQ / 微信 / 微博 的底层驱动 | 直连各平台开放平台 | 换成彩虹聚合登录(走你的彩虹服务端中转) | | 桌面端微信登录 | \`mode = qr\`,前端用聚合 appid 当微信 appid → 报「AppID 参数错误」 | 把这一条的 \`mode\` 改写成 \`redirect\`,前端改为跳转后端\*\*已经算好的\*\*授权地址(实测是真实可用的「微信扫码登录」页) | | GraphQL 的 \`gqSocialProvider\` 枚举 | 只有 7 个取值,没有 \`weibo\` | 抢在瓜奇之前注册同名枚举,把框架自带 7 个取值 + \*\*站点实际启用的渠道\*\*合并 | 几个关键设计: – \*\*不新增前端 UI\*\*。你站点上原来有几个登录按钮、排在哪,装完还是那样。 – \*\*不改瓜奇任何文件\*\*。补丁全在插件自己的代码里,卸载即恢复。 – \*\*凭据不另开一套\*\*。彩虹的 \`appid / appkey\` 直接复用瓜奇后台「注册设置 → 社交登录」里 QQ、微信、微博三项的 \`client\_id / client\_secret\`,不会出现两处配置打架。 – \*\*改不动的就不碰\*\*。微信在手机端、公众号 OAuth 等分支一律原样放行(下面第七节会解释为什么)。 \### 两处补丁的技术细节(给同行看的) \*\*补丁一:为什么必须「抢先注册」而不是「事后覆盖」\*\* 第一版我在 \`graphql\_register\_types\` 的\*\*优先级 99\*\* 上再调一次 \`register\_graphql\_enum\_type(‘gqSocialProvider’, …)\`,想盖掉瓜奇(默认优先级 10)注册的那份。结果完全不生效 —— 因为 WPGraphQL 的 \`TypeRegistry::register\_type()\` 对同名类型是\*\*静默跳过\*\*的: “\`php if ( isset( $this->types\[ $this->format\_key( $type\_name ) \] ) || … ) { graphql\_debug( ‘You cannot register duplicate Types to the Schema…’ ); return; // 直接放弃,连异常都不抛 } “\` 不报错、不覆盖。所以正确姿势是\*\*把优先级压到 5\*\*,抢在瓜奇之前注册,让瓜奇那次重复注册被跳过,由插件提供完整取值表。 \*\*补丁二:为什么微信改写的触发条件要收紧到「只改 qr」\*\* 瓜奇对微信其实有四种返回:\`redirect\`(已经可用)、\`qr\`(桌面端写死的那条,就是我们要修的)、\`official\`(微信内置浏览器的公众号 OAuth)、\`wechat-guide\`(手机端引导页)。所以要改的\*\*只有 \`qr\` 这一条\*\*: “\`php if ($mode !== ‘qr’) { return null; // 其余一律原样放行 } “\` — \## 三、装之前,先准备这四样 1\. \*\*一个跑瓜奇框架的 WordPress 站点\*\*,且后台能进「插件」页。 2\. \*\*一套彩虹聚合登录\*\*。两种选法: – 官方服务:\`https://u.cccyun.cc\` – 自建彩虹聚合登录系统(插件里填你自己的域名即可,插件会在后面拼 \`/connect.php\`) 3\. \*\*彩虹后台的 \`appid\` 和 \`appkey\`\*\*。在彩虹后台建一个应用,把 QQ、微信、微博三个渠道都勾上,然后拿到这一对凭据。 4\. \*\*你的前端域名\*\*。就是瓜奇渲染登录页的那个域名(例如 \`www.8maoku.com\`)。等一下要在彩虹后台登记成回调白名单。 \> 小提示:彩虹的渠道类型名和你平时叫的不一样 —— \*\*微信是 \`wx\`、微博是 \`sina\`\*\*。这个插件内部已经做了映射,你不用手动转,但你在彩虹后台勾渠道时要认得出来。 — \## 四、安装 插件提供两种形态,\*\*二选一,不要同时启用\*\*。 \### 方式 A:瓜奇运行时插件(推荐) 这是最贴合瓜奇用法的方式:走瓜奇自己的插件分发,前后端都认得,\`.git\` / 缓存目录不会残留垃圾。 1\. 进瓜奇后台的\*\*插件\*\*页; 2\. 上传 \*\*\`guaqi-rainbow-login-1.3.0.zip\`\*\*(35,741 字节,8 个文件); 3\. 装好后\*\*对本站点勾选「启用」\*\*。 \> ⚠️ \*\*一个坑必须提醒\*\*:瓜奇的运行时插件包,\`manifest.json\` 必须在 \*\*ZIP 根目录\*\*。如果你自己改包、把文件套进一层目录里,平台会直接判「ZIP 或 manifest.json 不正确」。上传就用原包,别解压再压。 \> ⚠️ \*\*另一个坑\*\*:\*\*不要用同一个版本号重传覆盖\*\*。同版本号重传会改变包的 checksum,平台会留下旧的 enable 记录,正好触发「runtime plugin generation already has different packages」这类报错。要换版本就升版本号。 \### 方式 B:标准 WordPress 插件形态(兜底) 如果你的瓜奇运行时插件机制本身有问题(例如平台前后端版本错配),可以先用这个形态把功能跑起来。 1\. WordPress 后台 → 插件 → 安装插件 → 上传插件; 2\. 上传 \*\*\`gqplus-rainbow-login-1.3.0-wp.zip\`\*\*(35,205 字节,7 个文件); 3\. 启用。 两个包装的是\*\*同一套源码\*\*,功能完全一致,只是入口文件不同。\*\*只能启用其一\*\*,同时启用会因为驱动抢占而互相打架。 — \## 五、配置(三步) \### 第 1 步:在瓜奇后台填彩虹凭据 进瓜奇后台 \*\*注册设置 → 社交登录\*\*,为下面三项分别填上彩虹给你的 \`appid\` 和 \`appkey\`: | 条目 key | 对应平台 | 彩虹 type | | ——– | —- | ——- | | \`qq\` | QQ | \`qq\` | | \`wechat\` | 微信 | \`wx\` | | \`weibo\` | 微博 | \`sina\` | \> \`client\_id\` 填彩虹的 \*\*appid\*\*,\`client\_secret\` 填彩虹的 \*\*appkey\*\*。 \> 插件不另开配置项,它直接读的就是这里。 \### 第 2 步:在插件设置页填彩虹服务端地址 进 WordPress 后台 \*\*设置 → GQPlus Rainbow\*\*: – \*\*彩虹服务端地址\*\*:官方填 \`https://u.cccyun.cc\`;自建填你自己的域名。插件会在其后拼 \`/connect.php\`。 – \*\*启用接管\*\*:默认开。关掉它就会\*\*立即恢复瓜奇原生直连驱动,不用停用插件\*\* —— 这也是最省事的回退方式。 \### 第 3 步:在彩虹后台登记回调白名单 彩虹需要知道「授权完之后把用户送回哪」。登记这个地址: “\` https://你的前端域名/authorize?type=qq “\` 三个平台分别登记(把 \`type\` 换成 \`qq\` / \`wechat\` / \`weibo\`)。 \> 插件设置页的「\*\*回车地址推导\*\*」这一行会直接把你站点该用的地址算出来显示,照着填就行,不用自己拼。 — \## 六、验证:装完怎么确认真的成功了 \### 1. 后台可视化面板 \*\*设置 → GQPlus Rainbow → 运行时接管诊断\*\*,会显示: – \*\*PHP 入口已载入\*\*:为「是」说明运行时插件确实被执行了; – \*\*钩子触发情况\*\*:\`plugins\_loaded\` / \`init\` / \`graphql\_register\_types\` / 驱动已挂载; – \*\*驱动槽位(关键)\*\*:qq / wechat / weibo 三个 provider 各自的驱动类名,判「本插件已接管」还是「被其它驱动占用」; – \*\*枚举改写\*\*:状态机四态 —— \`已生效\` / \`无需改写\` / \`失败\` / \`尚未观测到\`; – \*\*微信 mode 改写\*\*:最近一次 \`qr → redirect\` 的记录与时间; – \*\*响应改写自检(形态矩阵)\*\*:5 行全绿说明改写逻辑本身是对的。 \### 2. 匿名可读的 REST 接口 也可以在浏览器里直接访问(不返回任何密钥、绝对路径): “\` https://你的域名/wp-json/gqapi/v1/rainbow-status “\` \*\*只看四项:\*\* | 位置 | 期望值 | 含义 | | —————- | —————————- | ——- | | \`plugin.version\` | \`1.3.0\` | 装的是新包 | | \`drivers.owned\` | qq / wechat / weibo 全 \`true\` | 驱动槽位已拿到 | | \`enum.state\` | \`registered\` | 枚举已生效 | | \`self\_test\` | 5 行全 \`patched: true\` | 改写逻辑正确 | \### 3. 后台的两个一键自检 设置页里还有两个按钮: – \*\*测试彩虹连接\*\* —— 真发一次 \`act=login\`,并检查彩虹\*\*有没有把 \`state\` 原样带回回调地址\*\*。这一项是接入成败的关键(瓜奇要靠 state 校验防 CSRF,彩虹的回调默认不带 state,插件用的是「把 state 预拼进 \`redirect\_uri\`」的办法绕过去)。 – \*\*运行三平台自检\*\* —— 对 QQ / 微信 / 微博 各发一次,验证这套凭据在三个平台上是不是都能拿到跳转地址。这个检查在后台直接跑,\*\*不依赖前端会话\*\*,所以不会出现「其实没问题但面板说没生效」的误报。 \### 4. 最后,去前台真点一次 点\*\*微信登录\*\*,期望: – 直接跳到彩虹的扫码页(标题「微信登录」+ 二维码);\*\*不再出现「AppID 参数错误」\*\*。 – 回到诊断页,\`last\_patch\` 会出现一条 \`qr → redirect\` 的记录。 — \## 七、它改什么、它不碰什么 这一节建议你认真看一遍,能省掉不少「以为是 bug」的时间。 \### ✅ 会做的 – 接管 qq / wechat / weibo 三路驱动,走彩虹中转; – 桌面端微信 \`qr\` → \`redirect\`; – GraphQL 枚举补上站点实际启用的渠道(如 \`WEIBO\`)。 \### ❌ 不会碰的 | 不碰的东西 | 为什么不碰 | | ——————————— | —————————————————————————————— | | \*\*手机端的微信\*\* | 瓜奇在「非 PC 且非微信内置浏览器」时压根不调驱动,返回 \`wechat-guide\` 让用户去微信里打开。这是\*\*刻意设计\*\* —— 改成扫码页反而没用(手机扫不了自己屏幕)。 | | \*\*微信内置浏览器的公众号 OAuth(\`official\`)\*\* | 它本来就能用,动了只会坏。 | | \*\*\`redirect\` 模式的其它平台\*\* | 同理,已经可用。 | | \*\*任何新增前端 UI\*\* | 你站点的交互不变。 | | \*\*瓜奇的任何文件\*\* | 补丁只在插件内,卸载即恢复。 | \### 另外几点要有心理准备 – \*\*驱动槽是「谁最后写谁生效」\*\*。如果有别的插件(比如 gqplus 的一为聚合登录模块)也接管了同一个 provider,两者会抢同一个槽位。本插件在三次 \`extend\` 上挂载(含 \`graphql\_register\_types\` 优先级 99),线上到底谁赢了,\*\*以诊断页「驱动槽位」实测为准\*\* —— 那一行会直接给出驱动类名,不用猜。 – \*\*枚举只补「站点实际启用的渠道」\*\*。彩虹还支持支付宝、抖音等,但没出现在瓜奇「社交登录」列表里的渠道不会拿到枚举取值 —— 因为前端也不会渲染对应按钮。想让它们出现,得先在瓜奇后台把渠道加进社交登录配置。 — \## 八、常见问题(FAQ) \*\*Q1:装完了登录按钮没变化,是不是没生效?\*\* 先看诊断页的「驱动槽位」这一行。三个 provider 都显示「本插件已接管」才算拿到槽位。如果显示「被其它驱动占用」,说明有别的插件在更晚的时机注册了同名驱动,需要把它停用。 \*\*Q2:微信点了报「AppID 参数错误」?\*\* 这是前端把聚合应用号当成微信开放平台 appid 用了。请确认装的是 \*\*1.3.0 及以上\*\*,并在诊断页看 \`last\_patch\` 有没有 \`qr → redirect\` 的记录。没有的话,把诊断里 \`response.last\` 那段发出来 —— 它会直接给出各层的真实类型,不用猜。 \*\*Q3:微博点下去 403,报 \`Value “WEIBO” does not exist\`?\*\* 枚举没补上。同样是看诊断页的「枚举改写」状态。注意:\*\*\`graphql\_register\_types\` 只在 GraphQL 请求里触发\*\*,你打开后台页本身不是 GraphQL 请求 —— 1.2.0 因为把结果记在内存里,导致面板误报过「未生效」,1.3.0 已改成落库持久记录。 \*\*Q4:QQ 可以,微信和微博不行?\*\* QQ 走的是 \`redirect\` 模式,本来就通;微信卡在 \`qr\` 硬编码、微博卡在枚举。所以这个现象恰好说明\*\*补丁没生效\*\*,请检查驱动槽位与版本号。 \*\*Q5:手机端微信为什么不能用?\*\* 见第七节 —— 瓜奇本身就不让手机端走驱动,这是刻意设计。手机端要能用,得在瓜奇里配好公众号 OAuth。 \*\*Q6:和 gqplus 的一为聚合登录冲突吗?\*\* 会争同一个驱动槽位。\*\*彩虹直接替掉它\*\*就行,不要两个同时接管同一批 provider。 \*\*Q7:平台提示「runtime plugin generation already has different packages」,所有插件都在报?\*\* 这条\*\*与插件无关\*\*。它是瓜奇前端和 Node 端版本错配:Node 端没有 \`/api/runtime-plugins/state\`(请求返回 405),前端拿不到状态就按「不同步」判定,并把同一条错误统计到每张插件卡片上 —— 所以看起来「所有插件都报同一错」。需要把瓜奇两端升到同版本。 \*\*Q8:不想用了怎么退?\*\* 最省事的方式:设置页把「\*\*启用接管\*\*」取消勾选,\*\*立即恢复原生直连驱动\*\*,插件可以留着。要彻底清掉就正常卸载/删除插件,瓜奇文件未被改动过,卸载即恢复原状。 \*\*Q9:彩虹的 \`state\` 能回传吗?\*\* 彩虹的回调默认\*\*只追加 \`type\` 和 \`code\`,不回传 \`state\`\*\*。而瓜奇要用 state 做校验。插件的做法是\*\*把 state 预拼进 \`redirect\_uri\`\*\*。设置页的「测试彩虹连接」会专门验证这一项是否保持原样。 — \## 九、文件清单与校验值 \### 运行时插件形态(推荐) | 项 | 值 | | —— | —————————————————————— | | 文件名 | \`guaqi-rainbow-login-1.3.0.zip\` | | 大小 | 35,741 字节 | | 文件数 | 8 | | SHA256 | \`20db151142e548112356cd377898979506a57da773121ee57ce1f32d2efbb831\` | 包内结构: “\` manifest.json ← 必须在根目录 node/server/index.mjs wordpress/plugin.php wordpress/includes/class-social-bridge.php ← 驱动接管 + 两处补丁 wordpress/includes/class-rainbow-provider.php ← 彩虹 OAuth Provider wordpress/includes/class-rainbow-api.php ← connect.php 三接口封装 wordpress/includes/class-settings.php ← 后台设置页 + 自检 wordpress/includes/class-diagnostics.php ← 运行时诊断 + REST 接口 “\` \### 标准 WP 插件形态(兜底) | 项 | 值 | | —— | —————————————————————— | | 文件名 | \`gqplus-rainbow-login-1.3.0-wp.zip\` | | 大小 | 35,205 字节 | | 文件数 | 7 | | SHA256 | \`68b7f1ac47e1c2c30eb678fe8ef7161b7dc3a4b1cda24ff31b10fecc98a05ff5\` | — \## 十、写在最后 这个插件的定位很明确:\*\*它是补丁,不是框架\*\*。 – 它只解决「用聚合登录时,瓜奇的微信和微博会坏」这一件事; – 它不试图改造瓜奇的登录体系,也不给你加新玩法; – 它对瓜奇自身的两个发现(\`graphql\_response\` 是死代码、枚举必须抢先注册)对所有在瓜奇上做二开的人都适用。 装完如果还有异常,请在诊断页把 \`response.last\`、\`drivers\`、\`enum\` 三段一起抓出来 —— 它们给出的都是\*\*事实\*\*,比对着现象猜快得多。 — \*适用版本:瓜奇(GUAQI)框架 + WordPress。插件版本 1.3.0。\* /\* ============================================================================= \* 源码安全检测报告 · 展示样式 \* 说明:本文件同时供两处使用—— \* 1. 客户端运行时插件组件(node/client/components/0/index.js) \* 2. WordPress 服务端正文注入(wordpress/plugin.php 内联打印) \* 因此类名与结构必须保持一致,改这里就等于同时改两边。 \* 尺寸统一用 em,随模块缩放设置联动;颜色优先取 element-plus / 瓜奇主题变量, \* 并带固定色兜底,保证脱离主题也不花屏。不使用 color-mix 等新特性。 \* ========================================================================== \*/ .gqssr { --gqssr-primary: var(--el-color-primary, #00c29a); --gqssr-high: #e5484d; --gqssr-medium: #d98a00; --gqssr-low: #3b82f6; --gqssr-info: #8b8fa3; --gqssr-clean: #16a34a; --gqssr-line: var(--el-border-color, #e4e7ed); --gqssr-fg: var(--el-text-color-primary, #1f2329); --gqssr-fg-2: var(--el-text-color-regular, #4e5969); --gqssr-fg-3: var(--el-text-color-secondary, #86909c); --gqssr-bg: var(--el-bg-color, #ffffff); --gqssr-bg-2: var(--el-fill-color-light, #f7f8fa); --gqssr-code-bg: var(--el-fill-color, #f0f1f3); --gqssr-mono: ui-monospace, SFMono-Regular, SF Mono, Menlo, Consolas, "Liberation Mono", monospace; box-sizing: border-box; display: flex; flex-direction: column; gap: 1em; width: 100%; max-width: 100%; min-width: 0; font-size: 1em; line-height: 1.6; color: var(--gqssr-fg); } .gqssr \*, .gqssr \*::before, .gqssr \*::after { box-sizing: border-box; } /\* ---------------------------------------------------------------- 头部 \*/ .gqssr-head { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.75em 1em; padding-bottom: 0.875em; border-bottom: 1px solid var(--gqssr-line); } .gqssr-head-main { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5em; flex: 1 1 16em; min-width: 0; } .gqssr-title { margin: 0; padding: 0; border: 0; font-size: 1.0625em; font-weight: 600; line-height: 1.4; color: var(--gqssr-fg); } .gqssr-badge { display: inline-flex; align-items: center; flex: 0 0 auto; padding: 0.125em 0.5em; border-radius: 0.375em; font-size: 0.75em; font-weight: 600; line-height: 1.7; white-space: nowrap; color: #fff; background: var(--gqssr-info); } .gqssr-badge--high { background: var(--gqssr-high); } .gqssr-badge--medium { background: #d98a00; color: #fff; } .gqssr-badge--low { background: var(--gqssr-low); } .gqssr-badge--info { background: var(--gqssr-info); } .gqssr-badge--clean { background: var(--gqssr-clean); } .gqssr-chip { display: inline-flex; align-items: center; gap: 0.25em; flex: 0 0 auto; padding: 0.125em 0.5em; border-radius: 0.375em; font-size: 0.75em; font-weight: 600; line-height: 1.7; color: var(--gqssr-primary); background: var(--el-color-primary-light-9, rgba(0, 194, 154, 0.12)); border: 1px solid var(--el-color-primary-light-7, rgba(0, 194, 154, 0.34)); } .gqssr-meta { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: 0.375em 1em; font-size: 0.8125em; color: var(--gqssr-fg-3); min-width: 0; } .gqssr-meta span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; } .gqssr-meta b { font-weight: 600; color: var(--gqssr-fg-2); } /\* ---------------------------------------------------------------- 评分环 \*/ .gqssr-score { position: relative; flex: 0 0 auto; width: 4.5em; height: 4.5em; } .gqssr-score svg { display: block; width: 100%; height: 100%; transform: rotate(-90deg); } .gqssr-score .gqssr-ring-bg { fill: none; stroke: var(--el-fill-color, #eff0f1); stroke-width: 7; } .gqssr-score .gqssr-ring-fg { fill: none; stroke: var(--gqssr-info); stroke-width: 7; stroke-linecap: round; } .gqssr-score-inner { position: absolute; top: 0; right: 0; bottom: 0; left: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; line-height: 1; } .gqssr-score-num { font-size: 1.375em; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--gqssr-fg); } .gqssr-score-unit { margin-top: 0.125em; font-size: 0.625em; color: var(--gqssr-fg-3); } .gqssr\[data-level="high"\] .gqssr-ring-fg { stroke: var(--gqssr-high); } .gqssr\[data-level="medium"\] .gqssr-ring-fg { stroke: var(--gqssr-medium); } .gqssr\[data-level="low"\] .gqssr-ring-fg { stroke: var(--gqssr-low); } .gqssr\[data-level="info"\] .gqssr-ring-fg { stroke: var(--gqssr-info); } .gqssr\[data-level="clean"\] .gqssr-ring-fg { stroke: var(--gqssr-clean); } /\* ---------------------------------------------------------------- 概览统计 \*/ .gqssr-summary { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.5em; } .gqssr-stat { display: flex; flex-direction: column; align-items: center; gap: 0.125em; padding: 0.625em 0.25em; border-radius: 0.5em; background: var(--gqssr-bg-2); border: 1px solid var(--gqssr-line); min-width: 0; } .gqssr-stat-num { font-size: 1.125em; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.2; } .gqssr-stat-label { font-size: 0.75em; color: var(--gqssr-fg-3); white-space: nowrap; } .gqssr-stat--high { border-color: rgba(229, 72, 77, 0.32); } .gqssr-stat--high .gqssr-stat-num { color: var(--gqssr-high); } .gqssr-stat--medium { border-color: rgba(217, 138, 0, 0.34); } .gqssr-stat--medium .gqssr-stat-num { color: var(--gqssr-medium); } .gqssr-stat--low { border-color: rgba(59, 130, 246, 0.32); } .gqssr-stat--low .gqssr-stat-num { color: var(--gqssr-low); } .gqssr-stat--info .gqssr-stat-num { color: var(--gqssr-info); } .gqssr-struct { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375em 0.75em; font-size: 0.8125em; color: var(--gqssr-fg-3); } .gqssr-struct b { font-weight: 600; color: var(--gqssr-fg-2); } .gqssr-struct-label { font-weight: 600; color: var(--gqssr-fg-2); } /\* ---------------------------------------------------------------- 命中明细 \*/ .gqssr-findings { display: flex; flex-direction: column; gap: 0.5em; min-width: 0; } .gqssr-findings-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25em 0.625em; font-size: 0.875em; font-weight: 600; color: var(--gqssr-fg); } .gqssr-findings-head em { font-style: normal; font-weight: 400; font-size: 0.875em; color: var(--gqssr-fg-3); } /\* 区块标题:命中明细与后门特征排查共用(.gqssr-findings-head 是旧类名,保留兼容) \*/ .gqssr-sec-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25em 0.625em; font-size: 0.875em; font-weight: 600; color: var(--gqssr-fg); } .gqssr-sec-head em { font-style: normal; font-weight: 400; font-size: 0.875em; color: var(--gqssr-fg-3); } /\* ---------------------------------------------------------------- 按类别 \*/ /\* 把「风险项(参与评分)」与「加固建议 / 来源情报(不扣分)」分开摆, 报告读起来才是客观的 —— 后者不是缺陷,混在一起会让人以为问题很多。 \*/ .gqssr-cats { display: flex; flex-wrap: wrap; align-items: center; gap: 0.375em 0.625em; font-size: 0.8125em; } .gqssr-cats-label { font-weight: 600; color: var(--gqssr-fg-2); } .gqssr-cats-list { display: flex; flex-wrap: wrap; gap: 0.375em; min-width: 0; } .gqssr-cat { display: inline-flex; align-items: baseline; gap: 0.25em; padding: 0.125em 0.5em; border-radius: 0.375em; background: var(--gqssr-bg-2); border: 1px solid var(--gqssr-line); color: var(--gqssr-fg-2); white-space: nowrap; } .gqssr-cat b { font-weight: 700; font-variant-numeric: tabular-nums; } .gqssr-cat i { font-style: normal; font-size: 0.875em; color: var(--gqssr-fg-3); } .gqssr-cat--risk { border-color: rgba(229, 72, 77, 0.32); } .gqssr-cat--risk b { color: var(--gqssr-high); } .gqssr-cat--harden { border-color: rgba(217, 138, 0, 0.34); } .gqssr-cat--harden b { color: var(--gqssr-medium); } .gqssr-cat--intel { border-color: rgba(139, 143, 163, 0.34); } .gqssr-cat--intel b { color: var(--gqssr-info); } .gqssr-cat-groups { display: flex; flex-direction: column; gap: 0.75em; min-width: 0; } .gqssr-cat-group { display: flex; flex-direction: column; gap: 0.375em; min-width: 0; } .gqssr-cat-group-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.25em 0.5em; font-size: 0.8125em; font-weight: 600; color: var(--gqssr-fg-2); } .gqssr-cat-group-head i { font-style: normal; font-weight: 400; font-size: 0.875em; color: var(--gqssr-fg-3); } .gqssr-cat-group--risk .gqssr-cat-group-head span { color: var(--gqssr-high); } .gqssr-cat-group--harden .gqssr-cat-group-head span { color: var(--gqssr-medium); } .gqssr-cat-group--intel .gqssr-cat-group-head span { color: var(--gqssr-info); } /\* ---------------------------------------------------------------- 后门特征排查 \*/ /\* 未命中项也要逐条写出来:只列命中项的报告,读的人无法分辨 是「查过没发现」还是「压根没查」。 \*/ .gqssr-backdoor { display: flex; flex-direction: column; gap: 0.5em; min-width: 0; } .gqssr-bd-list { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.375em 0.625em; } .gqssr-bd-item { display: flex; align-items: center; gap: 0.375em; padding: 0.375em 0.5em; border-radius: 0.375em; background: var(--gqssr-bg-2); border: 1px solid transparent; font-size: 0.8125em; min-width: 0; } .gqssr-bd-item--clear { border-color: rgba(22, 163, 74, 0.22); } .gqssr-bd-item--hit { border-color: rgba(229, 72, 77, 0.38); background: rgba(229, 72, 77, 0.07); } .gqssr-bd-mark { flex: 0 0 auto; width: 1.125em; height: 1.125em; fill: none; stroke: var(--gqssr-clean); stroke-width: 1.4; stroke-linecap: round; stroke-linejoin: round; } .gqssr-bd-mark path:first-child { fill: rgba(22, 163, 74, 0.14); } .gqssr-bd-item--hit .gqssr-bd-mark { stroke: var(--gqssr-high); } .gqssr-bd-item--hit .gqssr-bd-mark path:first-child { fill: rgba(229, 72, 77, 0.14); } .gqssr-bd-title { flex: 1 1 auto; min-width: 0; color: var(--gqssr-fg-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .gqssr-bd-state { flex: 0 0 auto; font-style: normal; font-size: 0.875em; color: var(--gqssr-clean); } .gqssr-bd-item--hit .gqssr-bd-state { color: var(--gqssr-high); font-weight: 600; } /\* 评分口径说明 \*/ .gqssr-basis { margin: 0; font-size: 0.75em; line-height: 1.6; color: var(--gqssr-fg-3); } .gqssr-hit-list { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 0.5em; } .gqssr-hit { position: relative; margin: 0; padding: 0.625em 0.75em 0.625em 1.125em; border-radius: 0.5em; background: var(--gqssr-bg-2); list-style: none; min-width: 0; overflow: hidden; } .gqssr-hit::before { content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 3px; background: var(--gqssr-info); } .gqssr-hit--high::before { background: var(--gqssr-high); } .gqssr-hit--medium::before { background: var(--gqssr-medium); } .gqssr-hit--low::before { background: var(--gqssr-low); } .gqssr-hit--info::before { background: var(--gqssr-info); } .gqssr-hit-head { display: flex; flex-wrap: wrap; align-items: center; gap: 0.25em 0.5em; min-width: 0; } .gqssr-hit-head strong { font-size: 0.875em; font-weight: 600; color: var(--gqssr-fg); } .gqssr-hit-head code { font-family: var(--gqssr-mono); font-size: 0.75em; padding: 0.0625em 0.375em; border-radius: 0.25em; color: var(--gqssr-fg-2); background: var(--gqssr-code-bg); word-break: break-all; } .gqssr-tag { font-size: 0.6875em; font-weight: 600; padding: 0.0625em 0.375em; border-radius: 0.25em; color: var(--gqssr-high); background: rgba(229, 72, 77, 0.12); } .gqssr-hit-desc { margin: 0.25em 0 0; font-size: 0.8125em; color: var(--gqssr-fg-2); } .gqssr-hit-code { display: block; margin: 0.375em 0 0; padding: 0.375em 0.5em; border-radius: 0.375em; background: var(--gqssr-code-bg); font-family: var(--gqssr-mono); font-size: 0.75em; line-height: 1.5; color: var(--gqssr-fg-2); white-space: pre-wrap; word-break: break-all; overflow-x: auto; max-width: 100%; } .gqssr-hit-fix { margin: 0.375em 0 0; font-size: 0.8125em; color: var(--gqssr-fg-2); } .gqssr-hit-fix b { font-weight: 600; color: var(--gqssr-primary); } /\* ---------------------------------------------------------------- 页脚 \*/ .gqssr-foot { font-size: 0.75em; line-height: 1.6; color: var(--gqssr-fg-3); padding-top: 0.75em; border-top: 1px dashed var(--gqssr-line); } /\* ---------------------------------------------------------------- 窄屏 \*/ @media (max-width: 767px) { .gqssr-summary { grid-template-columns: repeat(2, minmax(0, 1fr)); } .gqssr-head { flex-direction: column; } .gqssr-score { align-self: flex-start; } /\* 窄屏下后门排查改成单列,8 项不至于挤成两行小字 \*/ .gqssr-bd-list { grid-template-columns: minmax(0, 1fr); } } 中低风险 ### 源码安全检测报告 已检测 82/100 检测引擎 **srcscan/1.3-php**报告编号 **SC-20261013-4D06AE**检测时间 **2026-10-13 21:12:11**内容发布 **2026-10-13 21:10:57**瓜奇(GUAQI)框架彩虹聚合登录插件 —— 安装教程与完整介绍 1高危 0中危 0低危 0提示 结构概览文件 **8**体积 **109.1 KB**代码文件 **6**代码行 **2,951** 按类别风险项 **1**_参与评分_ 后门特征排查_8 项特征全部未发现_ - 请求参数直接进入执行函数_未发现_ - 请求参数直接进入文件包含_未发现_ - 变量函数执行请求参数_未发现_ - 请求参数批量覆盖变量_未发现_ - 编码载荷后执行(混淆特征)_未发现_ - 回连裸 IP 地址_未发现_ - 配置预加载文件(隐蔽后门手法)_未发现_ - 向文件写入 PHP 代码_未发现_ 命中明细_共 1 项_ 风险项_参与评分_ - **远程升级 / 授权下发地址**`wordpress/includes/class-social-bridge.php:858` 配置中声明了远程检查更新或下载升级包的地址。若同时存在「下载 → 解压 → 覆盖站点文件」的逻辑,则厂商(或劫持该域名的人)可随时向你的站点写入任意 PHP 文件,属于可远程控制的交付通道。 ``` 'authorizationUrl' => 'https://login.example.invalid/jump.php?state=sandbox', ``` **建议:**核实域名归属:是不是作者自有域名?不是自有域名的升级/授权地址要特别警惕,建议直接移除或改成本地升级。 仅「风险项」参与评分,加固建议与来源情报只作呈现 本报告由 8号码库源码安全检测引擎(srcscan)静态扫描生成,用于上架前风险筛查,不构成安全保证。 **Tags:** gqSocialProvider, GUAQI, QQ 登录, WordPress 社交登录, WPGraphQL 枚举, 彩虹聚合登录, 微信扫码登录, 微博登录, 瓜奇框架, 聚合登录插件 **Categories:** 插件模块 ---