以下业务场景仅针对Web系统,Web页面有后台服务程序。第一年,我公司的用户数量达到了公司成立以来的新高峰。经过众多程序员夜以继日的加班加点,各个业务系统的稳定性几乎达到了四个九。获得了一定的人气。那天,一位商业伙伴突然上门拜访,并提出了双赢的合作意向。业务场景是我们的系统用户可以登录他们的系统,从用户那里获取一定的信息,进行一些业务操作。他们希望我们可以将现有用户数据的副本导入到他们的系统中,新注册的用户将进行单次同步更新。这不是虾扯蛋吗?.....为什么不?为了实现用户信息互通,满足业务需求,其实有很多解决方案。如果不是底线,同步用户信息的方案就是门外汉,扯淡的方案。你为什么这么说?首先,让我们谈谈信息同步。如果是单项同步,双方所有相关人员的工作量就已经很重了。在一定条件下,如果单项同步升级为双向信息同步,双方的程序员都会吃尽苦头。另外,无论工作量大小,用户信息本质上都是用户的隐私信息。用户可以安全地将他的隐私存放在你这里,这表明他对公司的信任。一旦出现复制用户信息的操作,本质上是对用户的不负责任,是道德和法律上的缺失。解决方案作为技术人员,有责任剔除不合理的方案,在业务可行的情况下提供技术方案。有没有不需要复制用户信息的低B方案?假设我们公司的系统是A,业务域名是www.A.com,第三方系统是B,业务域名是www.B.com记住我们最终的业务目标:让我们公司的用户(A系统)在第三方系统(B系统)可以登录,可以获取用户的一些相关信息。极端业务情况下,A系统用户修改相关信息并同步到B系统。解决方案一:在第三方系统的登录入口,让我们的用户输入账号密码,然后第三方系统(客户端或服务器均可)要求我司使用用户输入的账号密码登录服务器,验证通过后返回给用户。对于相关信息,第三方系统接收到返回的数据,按照自己的相关登录流程进行登录,可以存储用户相关信息。请求的形式和大致流程如下图所示http://www.A.com/login?loginname=caicai&pwd=buzhidao老实说,我不推荐这种方案,虽然比直接复制用户要好信息,但还有一个大问题。用户已经无形中将账户密码或其他登录凭据泄露给不受信任的第三方系统,而这可能不是用户想要的结果。方案二上述方案有一个致命的缺点,就是登录页面是用户不信任的第三方页面。如果能够避免这样的危险,让用户登录到我们信任的一方,将大大提升用户的信任度。从技术上来说,我们登录确实很容易,唯一需要考虑的就是用户登录成功后,如何将用户信息发送给第三方系统。如果我们使用请求调用的方式(比如:登录成功,我们调用第三方的接口),技术上是可以实现的,但是下次第三方申请这样的服务,我们的调用接口可能需要修改,所以现在业界更好更通用的方式是通过地址跳转来实现。具体过程如下:用户在第三方点击登录,跳转到我们提供的登录页面,页面的URL中包含登录成功的页面地址,并输入账号密码在本页。我们根据用户帐号和密码判断用户的正确性,成功登录,获取用户信息。然后跳转到第三方提供的登录成功跳转页面,把用户信息带上去。第三方跳转页面接收用户信息,处理剩下的业务,流程结束。第一步,第三方跳转到我们的登录页面URL如下:http://www.A.com/login?type=userinfo&redirecturi=http://www.B.com/callbackSolution32中的登录部分与方案一有本质区别,虽然只是改变了登录方,但是在安全性和用户隐私保护方面都有了很大的提升。但是,这个过程中仍然存在用户信息的主动传输。如果有人劫持,仍然存在用户信息泄露的风险。如何规避此类风险?试想,是否可以使用其他凭据代替用户信息?当然可以,这也是现代web系统实现授权的常用方式。用户信息被一个token代替,这个token具有一定的时效性,只能在一段时间内有效,在一定程度上保护了系统数据。第三方系统获取到这个token后,每次获取用户信息都会携带这个token作为凭证,而我们的系统也只把这个token识别为授权凭证。http://www.A.com/login?type=token&redirecturi=http://www.B.com/callback这里我想顺便说一下,token是通过前端(浏览器)的跳转传输发出的)到第三方系统,再由第三方系统前端传给后端,再由第三方后端携带token获取用户信息。注意,如果第三方前端页面携带token获取用户信息,是没有安全性的。方案四和方案三在很多情况下其实已经够用了,但是需要注意一点,每个token都有一定的有效时间,这是设计上的一个优势,同时也意味着如果token被别人拿到了,就可以是窃取用户信息,因为方案3中token的发行实际上是通过前端(浏览器)传输的,在前端传输的情况下,会有泄露的风险,那么有什么办法可以避免传输在前端毛呢?这里需要提醒一点,为了实现我们的用户可以登录第三方系统,在保护用户隐私的情况下,有必要在我们这边进行登录。而且,我们的系统必须给第三方系统颁发证书,才能满足第三方获取我们用户的要求。由于证书的传输是不可避免的,所以人们认为可以在前端(浏览器)传输一个只有一次有效的证书,然后第三方后端根据这个证书获取token,因为服务器的通信比前端(浏览器)更快。通信更加安全。于是方案4应运而生:用户跳转到我们的登录页面进行登录,我们验证用户名和密码是否正确,生成一个有效计数为1且在一定时间内有效的code,并携带这段代码跳转到第三方回调页面。第三方回调页面接收code参数,传给后台。程序。第三方后台程序接收code参数,携带code调用我们的接口,我们验证code的合法性,如果合法则返回token信息。第三方收到token信息,携带token信息调用我们的接口获取用户信息,我们验证token的合法性。如果有效,返回用户信息后的每次调用都会携带访问的token。即使代码被别人拿到了,也不行http://www.A.com/login?type=code&redirecturi=http://www.B.com/callbackUpgradeOption4看起来不错,其实不然完美的。当第三方跳转到我们的登录页面时,我们并不知道第三方是谁,也不知道他是否值得信赖,所以我们有必要识别第三方是否值得信赖。我们在授权第三方的时候,可以给每个第三方发一个类似appid,appkey的数据。appid用于标识每个我们授权的第三方,每个appid都必须注册一个回调url。这样当第三方跳转到我们的登录页面时,我们就可以判断第三方和回调重定向的URL是否合法。第三方携带code兑换token的时候,之后每一次携带token的通信获取用户信息,都需要按照我们的规则用appid和appkey进行签名,这样我们的服务器也可以识别调用者是否可信.在用户登录授权页面,用户可以查看自己授权给第三方的数据内容,这些权限会应用到code和token上。由于每个token都有过期时间,所以如何更新token会是一个技术点。实际上完全可以在发行令牌的同时发行更新令牌的令牌。重新发行令牌并更新它。每次我们的用户信息更新时,可以让相关的token失效,达到让第三方重新获取用户信息并同步的效果。我们的登录页面和所有第三方调用的接口都要使用https协议。并且所有第三方回调页面也必须使用https,可以有效模仿恶意劫持。不知道菜菜有没有教过对OAuth2.0授权不清楚的同学。如果还有不明白的,欢迎私信菜菜,获取更多精彩文章。
