Hello World

Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.

Quick Start

Create a new post

1
$ hexo new "My New Post"

More info: Writing

Run server

1
$ hexo server

More info: Server

Generate static files

1
$ hexo generate

More info: Generating

Deploy to remote sites

1
$ hexo deploy

More info: Deployment

开放式社交媒体个人备忘

https://fediverse.party

个人站点

WordPress

使用人数足够多,两边的插件都有,”千客“就是基于这个方案做的。在Blog方面应该非常强,有技术支持的情况下可扩展性也会很高。

microblog.pub

https://docs.microblog.pub/

相比Mastodon或许更适合个站? 单用户 AcitivityPub和IndieWeb的双向支持

Dolphin

轻量级的,适合个人使用的。前端型技术栈 , 二次开发门槛相对来说是比较低吧

IndieWeb + Fediverse

很多都是 Ryan Barrett 的作品

能转换各种社交网络间的数据。举例:可以把IndieWeb站点上的数据发布到Mastodon上

Bridgy

https://brid.gy/

Granary

https://granary.io/

https://github.com/snarfed/granary

转换数据格式,让支持各种协议的平台成为数据源

以API形式提供的,公开数据作为管道通过这类服务也还是可以的。最好有其他备选项。

对Matataki架构的一些思考

安全

  1. https://github.com/Matataki-io/Matataki-FE/issues/997 的回应

accessToken 如果放在非HttpOnly的Cookie里,脚本注入成功的话基本=拿到Token的值了。
API Server 和 Matataki-FE 并不在同一个domain下,Matataki-FE需要通过Header传递accessToken。如果是Android或是iOS这样的应用,那么找个相对安全的地方放置Token还是相对容易的,但是浏览器端都不好办,有的单页应用是直接放在被闭包保护的state里的,浏览器重新加载页面的话就重新登入。而要在有页面切换的应用使用,解决方案基本只会是Cookie,换成LocalStorage之类的地方只会更不保险。

大部分只是在开发层面上前端后端分离的,最后部署的时候还是会放在一个域下,站点前端控制器和API前端控制器分开来管理,前者做CSRF Token配合HttpOnly Secure Cookie传递SESSIONID或者JWT,后者用OAuth2,也更倾向和有后端的应用对接(不泄露ClientSecret),走authorization-code模式,安全性相对更高。

现在Matataki主站使用的基本是把两者当作一体对待的一般login,不过API Server Domain不同导致CSRF Token+HttpOnly Secure Cookie模式没法使用了。

而Developer平台提供的对接形式应该算是implicit模式的变种,应该是考虑到对接的APP不少是无后端的。

一般的APP用短期的JWT放在可被读到的Cookie里也还好,理由也是攻击的时间窗口并没有那么长,影响多少可控,而当前API涉及范围还挺大的,除了平台文章相关功能还包括Fan票部分,这里关系到用户的核心资产,如果授权了Fan票操作权限看来没有额度授权之类的,非常敏感了。

目前想到的主要改造思路:

  1. 权限进一步细化,授予Fan票相关权限的时候加上额度限制,并控制JWT的有效时长
  2. 涉及到转账、支付相关的API需要二次认证,可以有小额免密类的提升体验

这两个不调整架构也能做,要注意的细节会比较多,有API列表的话应该是针对特定API加强认证

对Matataki主站的改造可以考虑在matataki.io域名上搭一层薄的API转发网关,主站走这个API,accessToken放在主站的HttpOnly Secure Cookie里,在网关转发的时候把Token放到Header里提交给API Server

Developer那边也建议支持authorization-code,让第三方服务的后端也能用上HttpOnly Secure Cookie,现在的API Server模式在Server to Server的交互中使用。
现在的模式在静态Blog这种无后端的场景还是很有用,不过一个不注意是真的有可能从脚本泄露的。


如果Login Success在API Server的Domain下写HttpOnly Secure Cookie,API的调用根据条件检查Cookie和Header会如何呢?
没有其他后端的纯Client App/DAPP也没必要取这个Cookie里的JWT传给其他服务端,不能用JS读出来不是问题,有必要和其他后端交互的应用可以改造成authorization-code模式,在使用上似乎有优势。
问题在于一次登入就能在多个使用API的Client App应该是通用,会造成CSRF。即使根据申请的App来维护Cross-Origin清单,恶意站点如果去事先申请App,恐怕是没有那个精力去一个个审查的。这类跨站授权本来也是靠用户自己判断Client App是否值得信任,毕竟用户自己点授权的么。但是用户信任A站点生成的Token如果能被拿到B去使用性质就不一样了

如果是靠API返回值记录一个accessToken(和现在一样),再额外加一个HttpOnly Secure Cookie呢?
即使accessToken通过脚本泄露了,没有Cookie请求也无法通过;
即使在网站A请求到了Cookie,用户被某种方式引导带着Cookie访问危险站点B,没有accessToken也不行;
这样攻击就要再网站A构造脚本注入,读到accessToken后引导到危险站点B,两个都全了。那么签发accessToken的时候限定使用域,在B用这个accessToken请求会发现这个accessToken只能在站点A使用,也能拦截下来;

直接在Cookie里带上授权域信息也行,如果用同一个KEY,体验上会变成在其中一个App登入,另一个会被下线,从安全来说倒也不是问题;
如果不同的clientId写进不同的KEY里,accessToken里带上clientId,根据不同的clientId去检查不同的Cookie,应该能做到并存

这种模式下,API Server检查accessToken的逻辑是这样的:

  1. 判断API Endpoint是否需要accessToken才能访问,如果是没带accessToken,accessToken签名无法验证,accessToken过期等,拒绝
  2. 判断这个请求是不是带的accessToken是不是签发给谁的
    2-A. 是签发给某个服务端(可以包括matataki.io)的,如果是泄露的也说明服务端没尽到保管好accessToken的责任;不过还是可以通过检查请求头,请求IP等形式做进一步的安全判断,比如明显是通过浏览器发起的请求可以直接拒绝掉,不符合预设的使用场景;如果没有其他问题就判定通过
    2-B. 不是,是签发给浏览器前端使用的,判断是否有带上HttpOnly Secure Cookie(可以根据clientId检查不同的Cookie),如果有而且有效(格式也是一种JWT,不过内容和accessToken不同),那么通过,如果没有,拒绝
    2-C. 是签发给某个Mobile App的,按最普通的accessToken处理就可以了

PKCE解决的应该是clientSecret暴露在外的问题,本来也是Mobile App没有合适的放clientSecret位置的解决方案

https://www.oauth.com/playground/authorization-code-with-pkce.html

对SPA来说每重开一次都重新登录一次也不算不可接受了,涉及到币的话说不定反而是安全的证明
如果要更长时间保持,还是需要参考上面那种带些定制的手段了

有一些参考文章,可能有帮助:

https://wso2.com/library/articles/a-primer-on-oauth-2-0-for-client-side-applications-part-3/

https://developer.okta.com/blog/2019/05/01/is-the-oauth-implicit-flow-dead

  1. MatatakiAuth的JWT验证问题

当前是直接取JWT的payload解析回json使用的,没有验证签名。
通过userId+eth address等可以构造出这样的报文,有可能伪造身份。邮箱或者钱包地址在文章列表的author里是明文
userId在首页的url里就可以确认。
应该用签发JWT的KEY验证签名,为了减少KEY的扩散可以是生成JWT签名部分用privateKey,各个APP用publicKey验签

Hexo整合Matataki用Fan票打赏Blog文章

Hexo整合Matataki用Fan票打赏Blog文章

修改记录

  • 2020-12-14 初稿
  • 2020-12-15 修改方案,支持在目录页打赏

概述

在文章之后留下打赏地址/链接/二维码已经是一种很主流的激励创作者的形式了,Matataki的主站也支持用Fan票进行打赏。那么在站外我们能否用上Fan票呢?答案是肯定的。

如果已经有MetaMask这样的钱包,可以使用Fan票折跃门,把托管在平台上的Fan票转到我们自己的钱包,这样Blog上只要留下钱包地址即可转账打赏。

使用钱包仍然有些门槛,本文介绍了一种方法,可以当作站外使用Fan票场景的简单补充。这篇文章的成果很大程度上是基于

的研究:

使用的样例工程也是上文中提到的https://github.com/nekomeowww/hexo-plugin-matataki-example
这个方法工作量不大,只要做脚本集成就可以了,相对地,对Matataki的主站有依赖。

步骤

  1. FanLocker一样,我们在_config.yml里做好配置:
1
2
matataki:
userId: 4382

一般情况下整个Blog的文章都是自己的,打赏对象都是同一个人,所以不需要每篇文章分开来配置。这个userId可以在Matataki的个人主页看到,比如 https://www.matataki.io/user/4382

  1. 新建文件themes/landscape/layout/matataki.ejs,为Blog目录和每篇文章增加脚本片段
1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
var mttk = {
userId: '<%- config.matataki.userId %>',
open: function (href) {
window.open(href, 'hexo-mttk',
'width=445,height=700,resizable=no,menubar=no,status=no,scrollbars=yes');
},
openUserHome: function () {
let href = 'https://matataki.io/user/' + mttk.userId;
mttk.open(href);
}
};
</script>

然后在themes/landscape/layout/_partial/header.ejs里添加引用

1
2
3
4
<head>
<meta charset="utf-8">
<%- partial('matataki') %>

这样就在每个页面都声明了mttk对象

  1. 在博客的分享脚本里增加打开Matataki的链接。这个主题是在themes/landscape/source/js/script.js。找到Share部分,增加动态html脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Share
$('body').on('click', function(){
// ...

var html = [
'<div id="' + id + '" class="article-share-box">',
'<input class="article-share-input" value="' + url + '">',
'<div class="article-share-links">',
'<a href="https://twitter.com/intent/tweet?url=' + encodedUrl + '" class="article-share-twitter" target="_blank" title="Twitter"></a>',
'<a href="https://www.facebook.com/sharer.php?u=' + encodedUrl + '" class="article-share-facebook" target="_blank" title="Facebook"></a>',
'<a href="http://pinterest.com/pin/create/button/?url=' + encodedUrl + '" class="article-share-pinterest" target="_blank" title="Pinterest"></a>',
'<a href="javascript:mttk.openUserHome()" class="article-share-matataki" title="Matataki"></a>',
'</div>',
'</div>'
].join('');

//...
});

就是 '<a href="javascript:mttk.openUserHome()" class="article-share-matataki" title="Matataki"></a>',这句了。因为现在Matataki还不支持带入分享链接,先这样没有入参也是可以的

为了article-share-matataki这个样式,我们再调整一下css

  1. 打开themes/landscape/source/css/_partial/article.styl,增加如下样式:
1
2
3
4
5
6
7
.article-share-matataki
@extend $article-share-link
&:before
content: "\f087"
&:hover
background: color-google
text-shadow: 0 1px darken(color-google, 20%)

content这里是字体图标,可以去http://www.fontawesome.com.cn/faicons/找个自己喜欢的,比如:http://www.fontawesome.com.cn/icons/thumbs-o-up/,把里面的Unicode填到content:后就可以了,注意要加一个反斜杠 \

5.看看效果

image.png

image.png
这个点赞图标就是我们加上的打开Matataki页面的链接了。点击之后会弹出窗口,打开博主在Matataki的个人主页,也就是上面配置的userId

image.png

因为实际就是主站点,登录和转账的方式都是一样的

留言可以留博客链接

image.png

链接

体验地址

结语

这样一些希望能有完整的文章管理权而自建博客的用户也可以接入Fan票生态了。这种方案的中心化程度比较高,不过个人认为先小规模使用Fan票,熟悉之后再用【Fan票迁跃门】体验更进一步的去中心化也有其意义所在。

另一方面算是对Matataki和Fan票的关系的一种确认。这篇文章涉及到的应用场景和“在Matataki平台上写文章”没什么关系,只涉及到了Fan票相关的部分。也就是说这个基于Fan票打赏的博客也是Fan票宇宙的一部分,但和Matataki更像邻居(相当大程度是账号权限系统没分离,所以体感上都在Matataki的域名和页面的缘故)

理论上可以做到在web3层面开发直接对接Fan票的dAPP来为博客构建打赏方案,不过现在文档和工具都不完善,门槛还是过高了些,期待Matataki进一步发展后这方面能有所改善