为Typeco评论区启用QQ头像缓存

看了很多站点都支持了评论区使用QQ邮箱后自动显示QQ头像的功能,确实符合国内的网络环境,就想着给自己的博客也搞一个。

替换源代码调用官方接口

Type­cho目录下 var/Typecho/common.php ,大约1000行,找到获取 Gra­vatar 头像的代码:

public static function gravatarUrl($mail, $size, $rating, $default, $isSecure = false)
    {
        if (defined('__TYPECHO_GRAVATAR_PREFIX__')) {
            $url = __TYPECHO_GRAVATAR_PREFIX__;
        } else {
            $url = $isSecure ? 'https://secure.gravatar.com' : 'http://www.gravatar.com';
            $url .= '/avatar/';
        }

        if (!empty($mail)) {
            $url .= md5(strtolower(trim($mail)));
        }

        $url .= '?s=' . $size;
        $url .= '&r=' . $rating;
        $url .= '&d=' . $default;

        return $url;
    }

修改为:

public static function gravatarUrl($mail, $size, $rating, $default, $isSecure = false)
    {
            $reg = "/^\d{5,11}@[qQ][Qq]\.(com)$/";
            if (preg_match($reg, $mail)) {
                $img    = explode("@", $mail);
                $url = "//q2.qlogo.cn/headimg_dl?dst_uin={$img[0]}&spec=100";
            } else {
                if (defined('__TYPECHO_GRAVATAR_PREFIX__')) {
                    $url = __TYPECHO_GRAVATAR_PREFIX__;
                } else {
                    $url = $isSecure ? 'https://secure.gravatar.com' : 'http://www.gravatar.com';
                    $url .= '/avatar/';
                }
                if (!empty($mail)) {
                    $url .= md5(strtolower(trim($mail)));
                }
                $url .= '?s=' . $size;
                $url .= '&r=' . $rating;
                $url .= '&d=' . $default;
            }
            return $url;
    }

这个方法简单、高效,但是有一个问题,由于直接把用户QQ扔给官方接口返回头像,在网页的html代码内可以轻松找到评论者的QQ,这个问题说大不大,但也不是小事。由于我非常重视用户隐私,故这个方法不推荐使用。

使用QQ头像加密接口

万能的github,真的是什么都有。于是乎我发现了这个插件 GravatarServer Typecho

提供替换Gravatar服务器,支持QQ头像加密地址。 原作者 LT21 GravatarServer
由于原作者LT21最后更新于2015年3月,原有的Gravatar镜像已多数失效。 因此我收集了一些Gravatar镜像。
考虑到有些朋友没有gravatar头像,所以引入了使用QQ头像。
不久前一个朋友提到直接用头像会暴露qq,所以我找到了,腾讯qq头像加密地址。
比如https://thirdqq.qlogo.cn/g?b=sdk&k=s7FaiaNibSwRuBKft2wGnMzw&s=100&t=1552706192 目前解析不出QQ号。

试了一下确实很好用,但过了几天突然感觉博客变慢了。首字节响应时间一下飙升到8s多,赶紧开xdebug看看是怎么回事。
我一看竟然是curl_exec这个函数占据了大多数响应时间,思来想去,需要调取这个函数的,应该只有这个头像插件了(请求加密用户QQ时候调用国内的接口,但我的服务器在国外)。禁用插件之后博客速度立即恢复正常。
想了想解决方法,如果可以在用户刚提交完评论就把加密头像地址同时写进数据库,之后访客访问页面直接打开数据库,或许就能解决这个问题。但是我不会写php,也不知道这个加密头像地址是否会随着时间过期,更重要的是取得的加密链接说不定可以逆向(类比微博图床逆向UID惨案和BV号逆推AV号),无论速度还是安全性,我最终放弃了这个头像展示方法。

缓存用户QQ头像到服务器

过了一段时间想到既然Gravatar头像可以缓存到网站里调取,QQ头像也是可以的啊!
写代码?告辞不会。老样子上谷歌找方案。

好耶 ヾ(≧∇≦*)ゝ 找到了!现在我们Ctrl C一下就可以了(大雾

typecho头像缓存插件

Gravatar & QQ 头像缓存插件 For Typecho v3.0.1
非原创,修改该插件支持当用户使用数字QQ邮箱评论时显示QQ头像,且由于缓存机制,评论者不会对外泄露邮箱。 原作者出处:Byends

- 下载插件 GravatarCache.php.txt 去除.txt后缀
- 将插件上传到 /usr/plugins/ 这个目录下
- 登陆后台,在“控制台”下拉菜单中进入“插件管理”
- 启用插件即可

安装,启用。
成了!

但是还存在一点点小问题:

  1. 头像相当模糊,40px的大小无论在现代移动设备上还是电脑上都没有完美体验。
  2. 安全问题上虽然用md5加密的用户邮箱做文件名,但 qq@qq.com 的地址是有限的,通过生成字典来跑md5,暴力逆向用户邮箱并非难事(估计十位内的QQ邮箱也就数小时能告破)。
  3. 没有支援cdn镜像的设置。

花了些时间研究了各位dalao的代码,大概找到了解决方案
QQ头像接口支持100px的缩略图,这个清晰度对我胃口了。
md5只是用于命名头像文件的名字,所以直接加盐保存,避免惨案。
修改$siteUrl为cdn地址,可以加速头像载入(后来发现头像文件都不是很大,直接从源站加载也没问题)

淦!将作者原插件的175行左右起的部分代码进行修改,满足自己的需求。

//邮箱安全加盐和CDN设置
//如果你不需要CDN请保持此项为SiteURL
$imgcdnURL = $siteUrl;
//$imgcdnURL = 'https://cdn.yourdomain.com/'
//请设置一个随机数,不需要太长
$encryptSalt = 'KiF4a60g';

$timeCache = $option->timeCache;
$defaultMail = empty($mail) ? 'default' : md5( strtolower( $mail ) );
$defaultMailfile = empty($mail) ? 'default' : md5( strtolower( $mail.$encryptSalt ) );
$imgUrl = $imgcdnURL.$path.$defaultMailfile.'.jpg';
$baseFile = $dir.$path.$defaultMailfile.'.jpg';            

if(!file_exists($baseFile) || (time() - filemtime($baseFile)) > $timeCache){
    $mailstr=explode('@',strtolower($mail));
    if( $size == 40 && $mailstr[1]='qq.com' && file_exists($qqfile) && is_numeric($mailstr[0]) ){
        $size = 100;
               //修改QQ头像大小为100px
        $host = $isSecure ? 'https://q2.qlogo.cn' : 'http://q1.qlogo.cn';
        $avatar = $host.'/headimg_dl?dst_uin='.$mailstr[0].'&spec='.$size;
        if(!self::download($avatar, 'https://id.qq.com/', $baseFile)) copy($avatar, $baseFile);
        //if(filesize($baseFile) == 971 && filesize($file) != 911) copy($file, $baseFile);
    }else{
        $size = 144;
        $host = $isSecure ? 'https://secure.gravatar.com' : 'http://www.gravatar.com';
        $avatar = $host.'/avatar/'.$defaultMail.'?d='.$default.'&s='.$size.'&r='.$rating;
        if(!self::download($avatar, $referer, $baseFile)) copy($avatar, $baseFile);
        //if(filesize($baseFile) == 911 && filesize($file) != 911) copy($file, $baseFile);
    }
}        
return $imgUrl;
}

至此完美解决评论区QQ头像的问题。

添加新评论

已有 4 条评论

绝辣,我正想要找有关这方面的文章,不好意思我又来偷代码辣
我当时也装了权那他大佬的这个插件,过了几天也是博客变慢了很多,一直到今天才从你这里找到原因……之前我就是直接关掉插件一个个试的……

高清(雾 头像尺寸支持140140和640640

lawson lawson 回复 @lawson
0 0

* 会被markdown解析,好烦

100*100足够了,再大不实惠了