我们经常会看到微信登录某个第三方平台,那么在我们使用微信扫码后,平台是如何拿到我们的信息的呢?
这个可以在生活中找到模型
比如我们接收快递,快递小哥到楼下时会按门铃,此时家里的我们去接门铃电话,确认是快递小哥后就给他开门。
上述方法比较安全,但还不够高效,如果我们东西很多,小哥要分好8次才能送上来去接8次电话,听起来有点麻烦,所以我们设计了另外一种方案:告诉快递小哥大门密码,但是这个密码是暂时的,1小时后就会失效,这样的话我们就只要接听1次门铃电话,这个方案既安全又高效
而微信的第三方登录就是基于这个模型实现的。以下为扫码登录步骤
微信平台【小区大楼】就是储存了用户数据的网络服务,想要获取用户的信息,就必须经过微信的"门禁系统"。第三方应用如果想要【快递小哥】想要穿过门禁系统,拿到用户信息需要微信用户【我们业主】同意授权。
- 用户扫码,第三方发起微信授权登录请求【快递小哥按门铃电话】
- 微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;【我们接听电话,并确认确实是快递小哥,告诉门禁系统,我同意给予他进入小区的授权】
- 通过code参数加上AppID和AppSecret等,通过API换取access_token;【门禁系统得到我的确认以后,向快递小哥显示一个进入大楼的密码】
- 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。【小哥按密码进门,短时间内如果他没有忘记就不需要再给我打电话了】
其实这就是OAuth 2.0协议的应用
Oauth2.0协议
简单说,OAuth 就是一种授权机制。数据的所有者告诉系统,同意授权第三方应用进入系统,获取这些数据。系统从而产生一个短期的进入令牌(token),用来代替密码,供第三方应用使用。
令牌(token)与密码(password)的作用是一样的,都可以进入系统,但是有三点差异。
(1)令牌是短期的,到期会自动失效,用户自己无法修改。密码一般长期有效,用户不修改,就不会发生变化。
(2)令牌可以被数据所有者撤销,会立即失效。以上例而言,屋主可以随时取消快递员的令牌。密码一般不允许被他人撤销。
(3)令牌有权限范围(scope),比如只能进小区的二号门。对于网络服务来说,只读令牌就比读写令牌更安全。密码一般是完整权限。
上面这些设计,保证了令牌既可以让第三方应用获得权限,同时又随时可控,不会危及系统安全。这就是 OAuth 2.0 的优点。
注意,只要知道了令牌,就能进入系统。系统一般不会再次确认身份,所以令牌必须保密,泄漏令牌与泄漏密码的后果是一样的。 这也是为什么令牌的有效期,一般都设置得很短的原因。
用户识别
为了识别用户,每个用户针对每个公众号会产生一个安全的OpenID,如果需要在多公众号、移动应用之间做用户共通,则需前往微信开放平台,将这些公众号和应用绑定到一个开放平台账号下,绑定后,一个用户虽然对多个公众号和应用有多个不同的OpenID,但他对所有这些同一开放平台账号下的公众号和应用,只有一个UnionID
公众平台以access_token为接口调用凭据,来调用接口,所有接口的调用需要先获取access_token,access_token在2小时内有效,过期需要重新获取,但1天内获取次数有限,开发者需自行存储
微信小程序登录
微信通过凭证(code)进而换取用户登录态信息,包括用户的唯一标识(openid)及本次登录的会话密钥(session_key)等。用户数据的加解密通讯需要依赖会话密钥完成。
- 通过 wx.login 获取 code
- 将code 发送给第三方服务器
- 第三方服务器需要将 appid+appsecret+code,三者结合到一起,调用 auth.code2Session 接口发送给微信服务器
- 当微信服务器拿到 appid+appsecret+code,会返回给第三方服务器一些信息包括用户唯一标识 OpenID 、 用户在微信开放平台帐号下的唯一标识 UnionID(若当前小程序已绑定到微信开放平台帐号) 和 会话密钥 session_key。
- 项目服务器将 session_key 和 openid 保存下来生成 token 并返回给客户端
- 客户端把token保存下来,以后每一次发送请求必须携带 token