gitalk是一个基于github issue的评论系统,这个想法是非常具有创意的。不过一直以来这个项目都存在一些问题。
- 整个OAuth流程放在前端,暴露了client_id和client_secret
- github权限粒度较高,用户授权时会把仓库所有的权限授权出去,容易被人恶意利用
- 获取access_token是通过第三方api代理获取,有被恶意利用的可能
这几个重要缺陷一直是我的心头刺,因此我Fork了一份代码自己把这两个问题fix了。首先我把授权流程放到了server端,解决第一个和第三个问题。然后我新增了一个匿名评论功能,来打消访客的安全疑虑,同时匿名评论也能增加游客评论欲望。本文着重讲一下怎样实现匿名评论的功能。
Implementation
因为要新增一条issue的comment,必须要有一个github账号,我的思路就是用一个独立账号专门作为访客,用它的accessToken存放于服务端,访客提交匿名评论时,把评论提交到指定的server,由server完成创建评论的流程,返回给前端。整体流程如下
创建一个新的github账号
获取Personal access token
Account–>Settings–>Developer settings–>Personal access tokens–>Generate new token
Scope选项中 repo
和 user
是必选的。
最后生成access token,存放于服务端。
编写服务端api
gitalk原本是在客户端完成创建issue comment流程,虽然我们也可以把匿名账户的token写死在前端,不过这样很容易被恶意利用,所以我选择使用服务端代理github的api。
配置Gitalk
相对于原来的项目,现在新增了一个配置参数server
var gitalk = new Gitalk({
clientID: '',
clientSecret: '', //已废弃
repo: 'reponame',
owner: 'bigbyto',
admin: ['bibgyto'],
id: '',
perPage: 20,
server: {
oauth_api: 'http://oauthapi', //授权api
anonymous_api: 'http://anonymous_api' //
}
});
匿名评论请求信息
当配置了anonymous_api
时,如果用户点击了匿名评论
,将会发起一个post请求到anonymous_api
Url: anonymous_api
Method: POST
Content-type: application/x-www-form-urlencoded 因为存在跨域,为了防止发起preflight request
Body: postUrl=issueUrl&content=comment
具体案例可以直接在本博客的留言区发送一条匿名评论。
授权请求信息
用户点击登录时,跳转格式如下
http://oauthapi.com?origin=window.location.href
授权成功后会返回当前页面,且带上参数access_token
,该参数会被存到localStorage,切马上从url中删除。
总结
我对gitalk大致的改动就是这些,还有一些细微的调整,都是按照我个人意愿作出的调整。还有是这个改动不会向主项目发起pull request,因为风格差异太大。主项目把所有的东西放到了前端,我改动后把敏感的数据都放到后端,两者存在巨大差异。
仓库地址
有兴趣的话可以去看一下我的改动,仓库地址是