logo一言堂

用第三方网站登录

现代人都有很多很多个网上身份,在每个网站都有注册用户。假如你在每个网站都用密码登录的话,你可能:

  • 有很多很多密码,只好用密码管理器来管理。这密码管理器出问题怎么办?
  • 复用密码。但这是很大的风险,一个网站有问题你在别处的信息也面临风险。

现在还有第三种方法,就是用第三方,通常是比较大,有公信力的网站来登录,身份通行到别处。本文详细解释一下这包含的技术,以及你或网站所有者所可能面临的风险。

历史

一个身份,一次登录通行全网早就是用户的梦想。但是各种网站良莠不齐,之间也缺乏信任,如何做到这一点呢?其实业界早就有标准,甚至有两大阵营:OpenIDOAuth. 前者有大公司背书,但比较政治化,后者更注重技术,但各种可能性过多,不够兼容。到了近五年,两大阵营事实上已经融合。最新的Open ID Connect 标准实际上是对 OAuth2 的一种删节标准化,目前,所有主流网站实行的其实都是一个标准,就是OAuth2, 不管Google, Microsoft, Apple, Facebook其实都没什么本质不同,虽然细节上仍有各自差异。

今天,一个网站运营者现在可以轻松接入多家用户登录途径,只需要写少许代码,做一些对公众都开放的申请工作而已。如果你运行一个中小型网站,为你的用户方便,为自己方便,使用第三方大型网站来登录其实是不可或缺的功能。

技术分析

假如你运行一个网站,用户不管是用网页登录,还是用移动App登录,其实都是一样的。最终的目的是用户向你证明他是用户本人。但是在这个过程中,用户需要方便,和保护自己的秘密,所以输入密码其实是一件有风险的事情。在OAuth2框架下,登录过程分成若干步,其实比简单密码验证复杂的多,但用户在快速路径下,通常仅需要点击一个按纽,然后一切都水到渠成,无需用户干预。

步骤零

步骤零是你作为网站运营者做的,和用户无关。你事先需要到你想使用的大网站申请一个Oauth应用登录身份,它会给你发两个东西,一个是Client ID,其实就是你的网站在大网站,例如Google上的登录名,和Client Secret,可以理解成密码。后者一定要妥善保管,严禁泄密。

步骤一

你的用户在你的网站上发现可以使用第三方,比如Google登录。刚好这个用户有Google用户身份,所以他就点了这个按钮。这个按钮是你提供的,其实是一个链接指向你自己网站内部一个功能。你的程序会向用户返回一个HTTP 302 Redirect,到Google的专属OAuth登录入口,并附上你网站的ClientID。用户对你无任何输入,你尚不知道他是谁。

步骤二

在Google的专属OAuth登录入口,以下两者之一会发生:

  • 用户在Google已登录,有有效Cookie。这样跳过本步骤
  • 用户未登录

用户在Google网站上,使用Google标准界面登录,与暂时你完全没有任何关系。

步骤三

由于有你的client id,google知道这用户是你带来的。登录之后,google会立刻给用户呈现一个consent form,问用户,你是否想授权XXX网站,利用你的Google身份来验证你是谁呢?用户如果不同意,一切作罢。用户如果同意,则Google再做一个HTTP 302,转回你的网站之前在步骤零预留的callback入口,并附上一个Authorization Code(验证码)用户在这个consent form上做的选择会被Google记住,下次就直接跳转了。

步骤四

回到你的callback入口,现在你有了一个验证码。这样你自己,用这个验证码,和你自己的client id,client secret,向Google独立发一个请求。这个验证码有很短的时效性,虽然用户可能接触验证码,但他没有你的client secret,所以自己做不了任何事情。虽然用户也有可能篡改验证码,但这样验证码就失效了,最终也没意义。只有你,才能利用这个验证码,向Google申请一个Security Token(秘密令牌)。有了这个秘密令牌,对于Google来说,你就是用户自己本人(权限受限到consent form 限定的范围)。秘密令牌也有时效性,但长的多。

步骤五

你有了秘密令牌之后,通常再做一次Google请求,来读取用户profile。这个profile包含用户在Google预留的个人信息,如名字,邮件地址等,还包含用户在Google内部唯一识别用户ID。到这个时候,你再和你自己数据库对比,证明这个用户确实是他本尊,在你的网站上也是注册用户。

以上步骤中,步骤零四五和用户完全无关。步骤二三通常仅需做一次,之后就是一闪而过,甚至可能不闪(github就不闪)对于合法用户来说,最常见的就是仅需在步骤一点一个按钮,然后一切自动,几秒内就进来了。不仅方便,而且没有泄露任何秘密,安全可靠。

安全分析

有了以上的技术分析,我们可以看一下这之中是否有什么安全或隐私泄露隐患。分两个角度分析:

对终端用户

对终端用户来说,最重要的是仔细读这个consent form。这个网站究竟向大网站要了什么授权,有必要吗?对于简单网站登录来说,其实只需要read profile授权,就是以上步骤五。很多大型网站其实有丰富的API功能,以Github为例,你甚至可以授权让一个机器做你人能做的绝大部分操作。你当然不希望一个网站背着你做坏事吧。

由于这个consent form通常也只向你呈现一次(看多了也烦),所以,你需要了解,在google,microsoft等等你可能授权的地方,如何找到现有授权列表。这通常在管理界面藏的比较深的地方。每个用户都应该时不时看以下,都有些什么,是不是有什么不必要,可以删除的。删的唯一后果是下次登录还需要看一遍consent form。所以一切有疑问的删了便是。下面列出常见网站第三方授权管理界面:

有些小一点的网站没有类似管理界面,但每次呈现consent form,这样也罢,例如 wordpress. 假如管理界面找都找不到的,请三思使用。

对网站运营者

对网站运营者来说,你当然需要做一个好人,申请尽可能少的授权。另外还有一些考虑:

所有鸡蛋不要放在一个篮子里。你当然需要有尽可能大用户群的地方做验证,但假如它们想卡你也是分分钟的事。目前,如果你不是商业合作伙伴,Google和Microsoft对登录请求是有限流的。Github暂时没有限流。为自身安全,你至少要用两个以上的服务。

你也不希望你的用户三天两头点这个按钮。虽然自动,但也是有两三秒延时,影响用户体验。上面我提过Google,Microsoft有限流,而且你也不想Google对你的用户登录次数有直接统计不是。所以要做长期一点的用户session,让用户维持已登录状态。如果你的安全策略不允许长期登录,你的应用也不适合第三方登录了。

结束语

感谢技术进步,让一切成为可能。感谢良心企业向公众开放申请并自动批准,让个人架设的网站也能使用OAuth服务。互联网的成功来自开放和协作,过去如此,希望未来也如此。