这是一个为Typecho设计“微信/QQ登录”插件的详细技术方案。该方案结合了你提出的“电脑端授权”与“扫码登录”的需求,参考了现有插件的实现思路,并针对微信网页登录受限的现状提供了可行的替代方案。
一、需求分析与技术难点
根据你的需求,用户登录流程应具备智能判断能力:当用户在电脑上已登录微信或QQ客户端时,应直接跳转授权;若未登录,则展示二维码供用户扫描。
这里存在一个关键的技术限制:微信官方已于多年前关闭了普通的网页应用直接获取扫码登录二维码的接口。目前,微信开放平台仅允许通过认证的“网站应用”获取二维码,且需要复杂的审核流程 。因此,纯粹基于官方API的“免签约”PC端扫码实现起来难度较大。
针对这一难点,目前业界主要有两种解决方案,本方案将提供两套子方案供你选择:
- 官方标准方案:申请微信开放平台和QQ互联的官方应用,稳定性高,但微信端门槛较高。
- 聚合中转方案:使用第三方认证云服务(如QuickAuth),通过它们的中转接口间接实现,配置简单,适合个人博客。
二、插件总体架构
该插件将遵循Typecho的标准开发规范,主要包含以下核心组件:
- 主文件 (
Plugin.php):插件入口,负责激活、配置、路由注册和挂载点注入。 - 控制器 (
Action.php):处理所有登录请求、回调请求以及用户绑定逻辑。 - 数据库模型:创建额外的数据表用于存储用户ID与第三方OpenID的对应关系。
- SDK库:集成OAuth授权核心类库,用于生成授权链接、获取Access Token和用户信息。
三、核心功能实现方案
方案一:官方应用接入方案 (推荐用于生产环境)
此方案对接官方接口,稳定性最好,但需要在对应的开放平台注册应用。
1. 前期准备
- QQ登录:在 QQ互联 申请审核,获取
APP_ID和APP_KEY。 - 微信登录:在 微信开放平台 认证开发者,并创建“网站应用”,获取
AppID和AppSecret。
2. 智能登录逻辑实现
- 前端展示:在登录按钮旁增加判断逻辑。通过JavaScript检测用户PC端是否安装对应客户端(非官方开放能力,通常直接展示二维码)。
后端路由设计:
/oauth/login/qq:重定向至QQ互联授权页。/oauth/login/wechat:重定向至微信开放平台授权页。/oauth/callback/qq:QQ授权回调地址。/oauth/callback/wechat:微信授权回调地址。
3. 微信扫码的实现细节
由于微信官方标准OAuth在PC端必须通过扫码完成,流程如下:
- 用户点击“微信登录”。
- 跳转至微信开放平台提供的二维码页面(该页面由微信官方提供),或利用JS API生成二维码。
- 用户扫码并在手机确认后,微信服务器回调你配置的回调地址,携带授权
code。
方案二:第三方聚合接口方案 (基于QuickAuth,适合快速实现)
针对微信接口申请难的问题,可以使用第三方授权中转平台。该方案在搜索结果中被多次提及,如 QuickAuthLogin 插件 。
1. 原理
- 在QuickAuth等平台注册应用,获取
AppKey和UserSecret。 - 你的Typecho插件调用QuickAuth的接口,由QuickAuth再去调用微信或QQ的接口。
- 这种方式相当于将“开放平台认证”的成本转移给了第三方平台,对于个人博客来说非常省事。
2. 流程适配
- 用户在博客点击“微信登录”。
- 跳转到QuickAuth的中间页(或其提供的二维码页)。
- 用户扫码后,QuickAuth携带用户唯一标识回调你的博客。
- 你的插件通过
UserSecret解密用户数据,完成登录或注册。
四、数据表结构设计
为了支持多用户绑定和多登录方式,需要新建一张表(例如 typecho_oauth)来存储关联信息。
| 字段名 | 类型 | 描述 |
|---|---|---|
oid | int(10) | 主键ID,自增 |
uid | int(10) | 关联的Typecho本地用户ID ( typecho_users 表的 uid) |
type | varchar(50) | 登录类型,如 qq 或 wechat |
openid | varchar(255) | 第三方平台返回的唯一用户标识(非常重要) |
unionid | varchar(255) | 微信UnionID(如果有多个微信应用时使用,可留空) |
nickname | varchar(150) | 第三方昵称 |
avatar | varchar(255) | 头像地址 |
bind_time | int(10) | 绑定时间戳 |
逻辑说明:当用户首次通过QQ登录时,如果系统开启自动注册,则先在 users 表创建账号,再将 uid 和 openid 写入 oauth 表。如果是已登录用户绑定新账号,则直接写入已存在的 uid。
五、插件配置界面设计
在Typecho后台配置页面,需要包含以下选项:
登录方式开关:
- [x] 启用QQ登录
- [x] 启用微信登录
QQ配置参数:
- App ID:文本框
- App Key:文本框
- 回调地址:显示文本 (不可编辑,告知用户复制到QQ互联)
微信配置参数:
- App ID:文本框
- App Secret:文本框
- 回调地址:显示文本
注册与绑定设置:
- [ ] 允许未绑定用户自动注册(如果未勾选,则必须先在站内注册并绑定后才能使用第三方登录)。
- [ ] 启用PC端智能判断(理论上保留该选项,实际实现取决于SDK能力)。
界面定制:
- 登录按钮样式:默认/圆角/图标模式。
六、现有开源项目的参考
你可以参考以下两个活跃的Git仓库来加速开发:
- ThirdLogin (白雾林) :这是一个较新的项目,支持Typecho 1.2.1和PHP 8.0。它已删除了过时的登录渠道,保留了微信开放平台、微博、GitHub等。你可以借鉴其如何封装
ThinkOauth.php基类,以及如何处理微信登录回调的特殊逻辑 。 - QuickAuthLogin :如果你的目标是尽快实现“微信扫码”而不管官方审核,可以直接参考此插件对接QuickAuth平台的实现方式。它的代码结构展示了如何通过第三方接口免去复杂的官方申请流程。
七、注意事项与安全建议
- 回调地址一致性:无论是在QQ互联配置还是在插件后台配置,回调地址必须严格一致,否则会出现 redirect_uri 参数错误。
- 用户绑定机制:务必设计好“绑定/解绑”界面。要防止同一个第三方账号被绑定到多个本地账号,也要防止通过CSRF攻击恶意绑定他人的账号。
- 会话安全:授权登录成功后,建议生成新的Session ID,并重新生成登录凭证,防止Session Fixation攻击。
- 伪静态支持:如果你的博客未开启伪静态(PATHINFO模式),插件需要能够自动适应URL中携带
?=参数的格式 。
八、总结
你可以选择以下两条技术路线之一来编写这个插件:
- 稳健路线:基于
ThirdLogin的架构进行二次开发,申请官方微信开放平台和QQ互联接口,实现标准的OAuth登录。 - 便捷路线:基于
QuickAuthLogin的逻辑,对接聚合认证平台,重点实现扫码功能,但依赖第三方服务的稳定性。
无论选择哪条路线,上述的方案设计都能帮助你构建一个结构清晰、用户友好的“微信QQ登录”插件。
I appreciate the security advice section. Session fixation attacks are often overlooked by beginners. Good call out.
文章里提到的 ThirdLogin 和 QuickAuthLogin 两个仓库,我都去star了。准备结合你的方案,自己动手魔改一个。
伪静态支持这一点,很多插件作者都会忽略。你特意提出来,说明是真懂Typecho的人。赞一个!
The comparison between the two main solutions is very helpful. I'll probably go with the QuickAuth route for my small travel blog. Thanks!
之前用过某个第三方插件,经常掉线。看了你的架构分析,才知道原来是数据库模型和会话安全没处理好。受教了!