使用 QQ 互联实现QQ登录站点

QQ 互联相关的权限几年前就申请了,但是嫌麻烦没有去弄。
因为昨天的动森大头菜排队系统,群里有提到 QQ 机器人提醒登机,所以就去搜了下。结果发现,自从网页 QQ 挂掉后,QQ 机器人的实现只能靠模拟手机版 QQ,直接用 QQ 的协议进行数据交互。稍微搜了下几个比较常用的 QQ 机器人框架,感觉太繁琐了(毕竟相当于要实现一个没有前端的手机 QQ ),所以就弃坑了。

不过偶然又跳转到了 QQ 开放中心,然后想起了曾经申请的网页应用。于是就对着文档实现了基于 Go 的接口封装

根据文档的内容,基本上可以判定,这就是个半死的开放平台了:

  • QQ 互联官方文档工具的 QQ 互联都是不能用的
  • 有些接口数据返回的内容和文档写的不一样
  • 大部分接口都用于腾讯微博和QQ空间,QQ空间倒还好说,虽然充黄钻的少,但是用的人还挺多。但是腾讯微博……

尽管 QQ 互联问题很大,不过还是写了下模块,主要原因是今天代码没写,就开个坑,在 Github 上把今天绿了……

OAuth 2.0

QQ 互联使用的是 OAuth 2.0(之前在网易实习时,也实现过内部平台类似的登录方式),大概思路就是:

  1. 用户访问第三方站点,需要获取 QQ 的一些数据
  2. 第三方站点将用户跳转到 QQ 官方的页面
  3. 用户在 QQ 官方页面登录
  4. 登陆完成后,QQ 的页面把用户跳到第三方站点(并携带一个登录成功的证明——code
  5. 第三方站点拿着这个code以及自己的身份证明app idapp key去 QQ 的 API 申请令牌token
  6. 第三方站点拿着token去获取用户信息

搞得这么复杂主要是为了避免各种可能的攻击手段。

在这里,code是临时性的,并且申请到token后便作废了,真正用户授权给第三方站点的凭证是token
之所以多这么一步是为了避免往回跳转的时候由于一些奇怪的原因(劫持?)跳到不是用户想要授权的站点。因此还需要一个只有第三方站点才拥有的key来再次确认下身份。

实际上,很多 OAuth 2.0 的应用还需要在这一步进行加密,以增强安全性

文档

因为 QQ 互联目前用得上的接口就几个,基本上也就只能实现一个登录功能了

按照顺序调用各个函数即可

conn := qq.New("Your app id", "Your app key", "Your redirect uri")

token, err := conn.Auth(code)
if err != nil {
    return
}
output.Debug("%+v", token)

_, openID, unionID, err := conn.OpenID(token)
if err != nil {
    return
}
res, err := conn.Info(token, openID)
if err != nil {
    return
}

该模块要用到哪里

按照目前的思路,这个模块会更新到博客的用户系统里(目前实际上并没有用户系统)
当用户需要发布评论时,可以选择一键 QQ 登录(但是真的有意义么)
通过 QQ 互联,使用openIDunionID建立一个新的用户,并且设置昵称和头像,并要求其绑定邮箱(为了发送通知邮件用)

不过感觉把流程搞那么复杂会打消大家评论的积极性