微博作为大陆地区最大的社交媒体之一,其公共应用同样也较为出色。比如微博开放平台提供的登录、分享等能力,可以安全快捷的让小站长将自己的内容与微博连接,让用户无需跳出网站,就能将自己的内容通过无数的第三方用户扩散至社交网络。

本文旨在简单的介绍如何接入微博登录


说到“登录”之前,首先先聊下为什么要做“登录”。

传统的会员体系,是以访问用户为中心,每个用户拥有自己独一无二的会员标识,存储自己的个人信息,并拥有特定的应用权限。比如每个用户都可以储存自己独特的昵称、头像等信息,且与其他会员互不干扰,有的用户可以自由的发表文章或评论,而有的用户只能浏览网站上的内容。

正是由于网站上存有这些用户自己特性的信息,我们才必须将数据保护完备,不可让用户擅自修改。为了让用户只能够操作自己的会员数据,我们往往会通过密码的形式让用户在访问自己的数据前,先通过登录的动作来验证自己的身份。

登录功能的实验是非常简单的,仅需要在库中创建用户表,将用户的密码存入其中,用户在执行登录流程时,通过他传入的用户名及密码做校验,通过后为其授予身份校验通过的信息,并执行相应的权限处理。

但是,仅仅只做这些时不够的。

攻击者可能会通过字典遍历的方式暴力破解登录接口窃取用户信息,如果对于个人小站长来说,在登录流程中添加验证码、防刷等环节费时费力,还不一定能够做到完备,而这时我们就可以尝试通过安全防护更为强大的第三方所提供的符合OAuth 2.0协议的认证机制,代替我们自己来完成最为凶险的“登录”逻辑。

关于OAuth 2.0的内容可以点击这里 https://oauth.net/2/


微博开放的登录能力是通过 微博开放平台 提供的,作为一名个人开发者,注册一个微博帐号并通过开发者认证后,便可以将自己的站点信息登记在“我的应用”中。与很多同样也提供OAuth 2.0登录能力的平台不同,微博登录需要填写的信息更多,除了要填写基本的站点地址与回调地址外,必须要上传多个站点的图标 (16 * 16; 80 * 80; 120 * 120),以及三张应用介绍图片。

在所有信息填写完毕后,便可以“申请上线”,但是如果此时你的站点没有接入微博组件的话,审核通常是不会给通过的。为了能够尽快通过审核,建议在自己的内容页面中,先行接入“赞”、或者“分享”的组件。而接入组件这一步,对于已经全站https的站长朋友来说需要额外留意。微博官网提供的文档是存在问题的。

我们知道,在 Chrome 中,https 页面里动态的引入http 资源,比如引入一个js文件,会被直接block掉,在 https 页面里通过 ajax 的方式请求 http 资源,也会被直接block掉。

可能是因为移动互联网时代已经彻底取代了WEB端,和很多服务方一样,微博对WEB端的支持并不是很完备。按照分享按钮的 官方文档 介绍,分享按钮的接入代码只有3点。

  1. 在HTML标签中增加XML命名空间
<html xmlns:wb="http://open.weibo.com/wb">
  1. 在HEAD头中引入WB.JS
<script src="https://tjs.sjs.sinajs.cn/open/api/js/wb.js" type="text/javascript" charset="utf-8"></script>
  1. 在需要部署微博发布器的位置粘贴WBML代码
<wb:share-button appkey="YOUR APP KEY" addition="number" type="button"></wb:share-button>

当自己的站点仍然是 http 协议时,并没有太大的问题,而在全站 https 的页面下,控制台中就会出现以下报错信息:

Mixed Content: The page at 'xxx' was loaded over HTTPS, but requested an insecure resource 'xxx'. This request has been blocked; the content must be served over HTTPS.

出现这个问题的原因主要是微博组件会自动下载以下两个资源:

http://img.t.sinajs.cn/t4/appstyle/widget/css/shareButton/shareButton_v2.css?ver=201308281655
http://tjs.sjs.sinajs.cn/open/widget/js/share/shareBtn.js?version=201308281655

为了规避这个问题,我们可以通过在页面的<head>块中加入一行:

<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

这行代码的作用是在当前页面中,如果有发起http的访问,则自动将其转为https的请求。但是请特别留意,如果使用这个方法,必须保证自己的所有资源都已经完成了https的改造。

有趣的是,即便是微博的官方文档,也因为没有做此项处理,在 Chrome 下也是无法正确的显示出“分享”或“赞”等组件按钮。
注:本文写于 2020-02-17


完成微博组件的接入后,再次提交上线申请,一般就可以通过审核了。注:如果仍有问题,建议与微博开放平台联系。 在完成申请后,我们便可以利用微博开放平台提供给我们的App KeyApp Secret接入微博登录能力。

上文中OAuth 2.0的官方文档有提到完成登录授权的流程,简述就是:

  1. 跳转至第三方授权站点(带上参数 client_idredirect_uri 等);
  2. 在第三方站点完成登录,自动跳转回 redirect_uri 并附加 code 等参数;
  3. 在自己站点的回调页面根据参数 code 等向第三方授权站点发起请求获取 access_token
  4. 利用 access_token 向第三方授权站点发起请求获取用户信息;
  5. 将第三方站点的用户信息与自己库中用户数据做 mapping,如果自己站点用户存在,则完成登录流程,否则可根据需求做用户绑定或注册用户的处理。

大部分的第三方授权站点也都是按照这个流程为应用提供登录授权的能力,但是各家服务商的实现往往略有不同,例如 QQ互联 在登录后返回的就是不 code,而是直接就在跳转的URL中带上了 access_token。对于这种处理其实存在着不安全之处,攻击者如果拿到了URL,便可以直接利用 access_token 完成针对该站点在 QQ互联平台 进行定向的攻击。

而对于微博登录来说,主要流程基本与上述过程类似。但不同的是,微博登录在获取 access_token 后,需要先获取用户的 uid,然后再根据 access_tokenuid 再获取用户的信息。


登录是一个站点中最容易受到攻击,也是存在着很大安全风险的过程,建议小站长朋友尽量使用第三方登录的方式来保护用户数据。

但是我们一定也要记住,如果第三方平台关闭了登录的能力,我们的用户可能就无法再次访问我们的网站内容,所以一定要进行兜底方案的设计。比如要求用户绑定自己的手机号或邮箱,一旦第三方登录能力被关闭,我们还可以联系上用户,向其推送新的登陆方式。

前一篇:昨日有感
后一篇:如果,有一天。