智能小程序档案馆——登录授权

栏目: 后端 · 前端 · 发布时间: 5年前

内容简介:今天的档案馆系列,我们要为您介绍——智能小程序是如何实现使用百度App等宿主的帐号完成登录授权的。在完成登录授权的开发之后,使用者可以直接使用自己的百度帐号打开智能小程序。智能小程序在宿主应用中进行登录的方案是OAuth 2.0协议的变种,使用这种方案进行登录有如下优势:

今天的档案馆系列,我们要为您介绍——智能小程序是如何实现使用百度App等宿主的帐号完成登录授权的。

在完成登录授权的开发之后,使用者可以直接使用自己的百度帐号打开智能小程序。

智能小程序在宿主应用中进行登录的方案是OAuth 2.0协议的变种,使用这种方案进行登录有如下优势:

  1. 节省注册环节,直接使用宿主账号在小程序里登录。

    我们想象这样一个场景:小美在手百App中发现了一个很感兴趣的小程序,可是这个小程序有一套用户体系来识别用户,才能提供对应的服务,面对需要注册的弹出框,本来就没有什么耐心的小美,分分钟退出了小程序的页面。

    But!!如果使用 OAuth 系的登录方式,小美就可以直接使用宿主账号在小程序里登录,进入智能小程序开开心心的继续划手机~

  2. 帮用户免去忘记帐号的烦恼,提高应用的安全性。

    我们继续想象:依然是小美,被各种小程序深深吸引的小美,因为记不住那么多不同的用户名、邮箱、密码,果断选择使用相同的用户名、密码等信息。但其实这hin危险,一旦用户数据泄露后入侵者可以拿这些数据去尝试登录其它智能小程序,从而入侵其它原本安全的应用,这种即是常见的“撞库”攻击。

    而使用OAuth系的登录方式,一般应用将用户登录的安全校验托管给提供OAuth服务的应用,可以避免被“撞库”的风险,提高应用的安全性。

使用宿主的账号体系进行登录的全流程可见小程序开发文档中的 登录 章节,详情请戳: smartprogram.baidu.com/docs/develo…

本文将对OpenID和Session Key的获取进行详细的说明,大家可以看一下下面的这幅授权流程图,可以看到Session Key在整个流程中有着十分重要的作用。

智能小程序档案馆——登录授权

什么是OpenID和Session Key

  • OpenID:是宿主为每个用户在每个小程序中生成的用户标识,一个相同的OpenID可以始终对应同一个宿主账号的用户。

  • Session Key:是宿主为每个用户在每个小程序中生成的数据密钥,数据密钥有两个重要的作用:首先是通过宿主提供的接口获取到的数据会使用Session Key加密,可以保证开发者服务端拿到的数据是真实有效的,其次Session Key。会有更新机制,保证用户登录信息的安全。后面会在登录标识章节再详细讨论。

获取OpenID和Session Key

小程序获取用户的OpenID和Session Key的流程图如下:

智能小程序档案馆——登录授权

swan.Login()、swan.request等接口信息请戳: smartprogram.baidu.com/docs/develo…

  1. 智能小程序在App内部运行时使用swan.login()接口获取Authorization Code;

  2. 通过 Authorization Code 获取 Session Key ;

  3. 调用 getUserInfo 获取用户信息;

  4. 当用户完成了授权,且授权会话仍处于有效期时,智能小程序不需要每次都进行前两步,而是可以直接进行第三步获取用户信息。

需要特别提到的一点是:swan.Login()不需要用户授权,也就是说在用户已登录宿主账号的情况下整个流程是完全静默完成的,但是当用户在宿主应用上并未登录的时候,调用此接口会弹出宿主应用的登录窗口,用户需要完成登录后再继续进行。如果需要在用户未登录的时候做其它逻辑处理而不是要求用户登录,可以先通过swan.IsLoginSync()判断用户的登录状态。

登录标识

当开发者获取到用户的OpenID和Session Key之后,开发者应该生成一个唯一的登录标识返回给小程序,并写到小程序的本地存储中,在后续的请求开发者的服务端接口时通过参数带上这个唯一标识,供后端通过这个登录标识找到对应的OpenID和Session Key。

一种比较好的登录标识的设计范例是: Hash(OpenID + SessionKey + Salt) ,其中Salt是开发者自己定义的一个随机字符串,Hash可以考虑使用SHA1或者MD5等碰撞概率非常小的哈希函数。

不建议大家直接使用OpenID或Session Key的明文作为登录标识。

  • 使用 OpenID 作为登录标识的风险在于,同一个账号的OpenID永远不会变,因此若攻击者获取到某个用户的OpenID,则可在参数中一直使用此OpenID来伪装成此用户访问开发者的服务;

  • 使用Session Key明文作为登录标识的风险在于,攻击者不光可以直接使用此Session Key解密用户数据,还可以使用它加密出假的用户数据,然后通过开发者提供的服务端提口篡改用户的数据。

总结来说,登录标识需要满足:唯一性、有时效性,并不能带上敏感信息。

使用Session Key处理用户数据

当获取到Session Key和OpenID后,开发者就可以获取到有效的用户数据了。获取用户数据主swan.getUserInfo()和swan.getPhoneNumber()等接口。

下面以swan.getUserInfo()为例, 讲解如何使用Session Key安全有效地处理用户信息。

swan.getUserInfo()接口返回的内容可以分为明文和密文两部分,

  • 明文部分是为了可以更快地显示在小程序的页面上,主要包括用户的头像、昵称等信息;

  • 密文部分是data和iv两个字段。

当进行消息推送时,开发者可能需要在消息内容里以“亲爱的XXX”为开头,此时会用到用户的OpenID和真实的用户名。

如果开发者提供一个接口,在通过swan.getUserInfo()获取到用户信息后直接将用户信息以明文的方式发到开发者自己的服务端某个接口中保存起来,就会出现一个安全问题:攻击者可以伪造用户的名称等各种信息来访问开发者的服务器写入假的用户数据。

安全的做法是

  1. 开发者在前端获取到swan.getUserInfo()后,将上一节中所说的用户登录标识从LocalStorage中取出来,加上data和iv,将这三个数据发到自己的服务器;

  2. 先通过登录标识将SessionKey取出来,然后SessionKe和iv一起使用AES-192-CBC算法对data进行解密(解密详细的过程及代码示例可参见 用户数据的签名验证和加解密 );

  3. 通过判断解密是否成功,以及解密出的OpenID是否与登录标识所关联的OpenID一致来判断数据的真实性,再保存到自己的数据库中。

特别说明一点,调用swan.getUserInfo()这类接口会弹出授权提示框让用户进行授权,若用户拒绝授权,再次调用此接口不会重复弹出授权提示框。开发者此时可引导用户重新授权,并调用swan.openSetting()让用户重新授权。

SessionKey有效性判断

由上两节可知,开发者每次获取用户信息的时候,需要同时判断本地是否有用户标识,以及Session Key是否有效:

  • 若没有本地标识,则无法找到对应的SessionKey;

  • 而若SessionKey已经无效,说明开发者数据库中的用户SessionKey无法对宿主所提供的data和iv进行解密。

    判断SessionKey是否有效可以通过调用swan.checkSession()来判断。如果为false,则走上述获取SessionKey的流程重新让用户使用宿主账号在小程序内完成登录;若为true,则说明不用重新换取SessionKey,可以直接获取用户信息。

需要注意的一点是,在提供多点登录的宿主应用(例如百度App)中,有可能同一个账号会在多台不同的设备上同时登录,此时有可能会出现此账号在多台设备上先后都换取过Session Key,但是在此过程中Session Key发生了变化,则变化前已换取过Session Key的设备上,本地存储中的登录标识已经失效(找不到对应的Session Key),而调用swan.checkSession()仍然会得到true,此时开发者应当在登录标识已失效的设备上处理此类异常,重新换取Session Key并生成新的登录标识。

未登录时的降级方案

由于宿主应用并不一定强制用户登录,因此用户也有可能处于未登录状态。此时开发者可能不希望通过调用swan.login()强制用户登录,而是希望直接使用用户的设备标识来关联用户,存储一些非敏感的数据。因此智能小程序还提供一个SwanID的标识,可视作用户的设备标识。SwanID可以通过swan.getSwanId()获取( 接口文档 )。SwanID具有以下特征:

  1. 用户在同一台设备上使用同一个开发者所开发的不同智能小程序,得到的是相同的SwanID。

  2. 用户在同一台设备上使用不同开发者所开发的不同智能小程序,得到的SwanID是不同的。

灵活地使用SwanID和OpenID进行搭配,可以做到许多特殊的功能,例如:

  • 在未登录的时候,将数据与用户的SwanID关联,当用户登录后,通过SwanID找到用户登录前的数据,然后OpenID关联,比如常见的场景例如电商类小程序对购物车数据的同步。

  • 通过SwanID限定一个指定的OpenID只能在一台设备上使用某个小程序,即当同一个OpenID先后出现了两个SwanID时,可以将前一个SwanID的登录态踢出,比较常见的有IM类的小程序。

总结

  1. 开发者可使用OpenID+Session Key的方式使用宿主的用户体系完成自己的业务需求。

  2. 安全地处理OpenID和Session Key,不直接暴露到前端,而是基于它们生成用户的登录标识,保证登录标识只在有效期内可用非常重要。

  3. 当用户拒绝授权获取用户信息时,再次调用swan.getUserInfo()方法无法重新弹框让用户同意,此时可通过swan.openSetting()方法让用户重新授权。

  4. 当用户未登录时,可使用SwanID作为降级方案,处理一些不太敏感的业务。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

持续交付

持续交付

Jez Humble、David Farley / 乔梁 / 人民邮电出版社 / 2011-10 / 89.00元

Jez Humble编著的《持续交付(发布可靠软件的系统方法)》讲述如何实现更快、更可靠、低成本的自动化软件交付,描述了如何通过增加反馈,并改进开发人员、测试人员、运维人员和项目经理之间的协作来达到这个目标。《持续交付(发布可靠软件的系统方法)》由三部分组成。第一部分阐述了持续交付背后的一些原则,以及支持这些原则的实践。第二部分是本书的核心,全面讲述了部署流水线。第三部分围绕部署流水线的投入产出讨......一起来看看 《持续交付》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码