❗ 本文最后更新于 3336 天前,文中所描述的信息可能已发生改变,请谨慎使用。
我的博客之前一直部署在 Linode,使用 Disqus 提供的评论服务。Disqus 作为第三方社会化评论的鼻祖,无论功能还是体验,都堪称完美。虽然之前 Disqus 经常加载失败,我也一直在坚守。最近我的 Linode 持续无法访问,几番折腾之后还是换到国内云主机并备案了。借着这次机会,我也把评论从 Disqus 迁移到了国内的多说。多说官方对 HTTPS 的支持并不完美,本文记录我对它的几处改造。
Disqus 和多说都是根据指定 ID 进行评论聚合的第三方系统,将页面上 Disqus 的引用代码换成多说的代码,再按照文档改改参数,评论功能就迁移完成了。数据迁移可以使用前人造好的轮子,例如 Github 上的 GavinFoo/DISQUS2DUOSHUO。功能和数据迁移都很简单,这里略过不写。
我的网站配置了 CSP 策略,需要把多说用到的域名配置到白名单之中。以下是本站 CSP 全部规则:
content-security-policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: https://*.duoshuo.com; img-src 'self' data: https://*.duoshuo.com; style-src 'self' 'unsafe-inline' https://*.duoshuo.com; connect-src wss://*.duoshuo.com:* https://*.duoshuo.com
多说的种子文件支持 HTTPS,直接把官方地址替换为 HTTPS 即可。但多说有几个地方没考虑周到,需要额外处理:1)用户头像,多说支持多种第三方登录方式,用户头像也支持使用了第三方地址,而这些地址基本都是 HTTP;2)表情,在多说选择表情的浮层中,只有 wordpress 分组中的表情放在多说服务器上并支持 HTTPS,其余分组全部直接使用了 Sina 微博的 HTTP 地址。另外多说评论正文中的表情,也需要替换为 HTTPS 地址。
要解决用户头像问题,可以借用本站 HTTPS 做一个反向代理。我在 Nginx 配置增加了以下内容:
proxy_cache_path /home/xxx/proxy_cache_path levels=1:2 keys_zone=pnc:300m inactive=30d max_size=10g;
proxy_temp_path /home/xxx/proxy_temp_path;
proxy_cache_key $host$uri$is_args$args;
server {
... ...
location ~ ^/proxy/(\w+\.)(bdimg\.com|cdncache\.org|douban\.com|gravatar\.com|qlogo\.cn|sinaimg\.cn|xnimg\.cn)(\/.*)$ {
valid_referers blocked server_names;
if ($invalid_referer) {
return 403;
}
proxy_connect_timeout 10s;
proxy_read_timeout 10s;
proxy_pass http://$1$2$3;
proxy_cache pnc;
proxy_cache_valid 200 30d;
proxy_cache_lock on;
proxy_cache_lock_timeout 5s;
proxy_cache_use_stale updating error timeout invalid_header http_500 http_502;
add_header X-Cache "$upstream_cache_status from cache.ququ";
expires max;
}
location ~ ^/proxy/(.*)$ {
valid_referers blocked server_names;
if ($invalid_referer) {
return 403;
}
rewrite ^.*$ /static/img/blog/default_avatar.png last;
}
... ...
}
以上配置做了几件事情:1)针对白名单中的 URL 做了反向代理,针对白名单之外的 URL 输出默认头像;2)通过 Nginx 的 proxy_cache 以及 HTTP 的缓存机制,增加访问速度;3)针对这个 proxy 服务启用了严格的 referer 限制(空 referer 都不允许)。
有了反向代理之后,可以对多说的 embed.js
动手术了。我没有找到无侵入的补丁方式,只能粗暴地将官方 embed.js
托管在本站进行修改。一共修改了以下几处(为了看得更清楚,我加入的代码放在注释里):
avatarUrl: function(e) {
/*
if (e.avatar_url) {
e.avatar_url = e.avatar_url.replace(/^http\:\/\//, "https://imququ.com/proxy/");
} else {
nt.data.default_avatar_url = '/static/img/blog/default_avatar.png';
}
*/
return e.avatar_url || nt.data.default_avatar_url
}
这处修改,是让多说用户头像走前面配置的 proxy 服务。对于无头像用户,我直接返回了默认头像地址,减少一次 proxy。
addSmilies = function(e, t) {
/*
if(e !== 'WordPress') return;
*/
var s = j.smiliesTooltip;
s && s.el.find("ul.ds-smilies-tabs").append("<li><a>" + e + "</a></li>"), j.smilies[e] = t
}
这处修改,是让多说不加载 Wordpress 之外的分组表情。由于只剩下一个分组,所以表情浮层样式我也微调了一下,具体效果请看本文评论(实际上,多说评论的样式我改了好多处)。将 Sina 微博表情替换为 proxy 地址,或者是传到支持 HTTPS 的 CDN 也可以,但我觉得没有必要。如果图省事,也可以直接在多说后台关闭评论表情功能。
var t = "",
s = e.post,
i = e.options,
r = s.author;
/*
s.message = s.message.replace(/http:\/\/static\.duoshuo\.com\//g, 'https://static.duoshuo.com/');
*/
if (t += '<li class="ds-post" data-post-id="' + s.post_id + '">...'){
...
}
这处修改,是将评论内容中的表情地址由 HTTP 替换为 HTTPS。
经过以上处理,多说评论所需资源全部会走 HTTPS 了。由于多说代码会更新,本文具有一定的时效性,大家可以参考我的做法自行修改,不要照搬代码。
另外,多说没有 Disqus 那样的新评论通知邮件,我是通过 Github 上的 zhengxiaopeng/duoshuo-comment-notification 项目实现即时提醒的。
最后,我在迁移 Disqus 到多说的过程中,参考了以下两篇文章,在此表示感谢:
注:一番折腾之后,我还是回归了 Disqus,详情请见 »
本文链接:https://imququ.com/post/duoshuo-and-https.html,参与评论 »
--EOF--
发表于 2015-09-27 12:46:09,并被添加「QuQuBlog」标签,最后修改于 2015-10-14 01:28:24。查看本文 Markdown 版本 »
Comments
Waline 评论加载中...