小程序授权登录注册自有账户体系

  现在一般的应用都有自己的账户体系,那么扩展了小程序前端入口后,大家都在思考用微信的授权实现自有账户体系快速登录/注册问题。正好最近公司的小程序也要想上这个功能,替换掉不必要的短信验证码快捷登录注册的业务场景,我也整理了下自己的思路,与大家分享和探讨一下基于安全前提下的小程序授权登录/注册问题。

一、前提说明
1.安全,对于数据,后端服务器永远是不相信前端传值的,因为后端只能判断接收既定规格的数据,而判断不出数据合法性。
2.安全, 对于网络,我们使用自定义验签加密(前后端统一定义规则)+https加密方式来防止网络抓包后请求数据的篡改。
3.安全,对于模拟攻击,2中的自定义验签加密算法规则又依赖于黑盒环境,不然一切都是徒劳,等效于裸奔,所以我们会使用一些市面上比较成熟的商用加固软件对应用加壳及核心数据白盒加密,来确保前端应用中自定义验签加密算法及配置的黑盒环境,防止他人对应用砸壳获取验签规则,模拟请求。
4.安全,对于无法保证源码黑盒环境下的客户端,三方的数据我们可以通过自有服务器服务与三方服务器通过既定验签规则保证数据的合法性
5.现在我们的C端系统,账户一般都基于用户手机号,我们下面聊的也是基于这种场景。
6.微信体系获取用户微信绑定手机号目前只支持小程序,且仅支持前端授权回调获取,后端不能通过api获取。
7.小程序开发语言和前端h5开发差不多,离不开「前端三件套」——HTML(WXML)、CSS(WXSS)、js
①HTML-WXML(WeiXin Mark Language,微信标记语言)
两者差异比较大,如果之前没有接触过 Android 开发,可能会觉得有些头疼。事实上,WXML 更像是 Android 开发中的界面 XML 描述文件,适合于程序界面的构建;而 HTML 则倾向于文章的展示(这与 HTML 的历史有关),以及互联网页面的构建。
②CSS-WXSS(WeiXin Style Sheet,微信样式表)
两者在语言上几乎没有差别,可以直接通用。
③JS(小程序的主体)
小程序的 JS 文件与前端开发使用的 JS 几乎没有区别,只是小程序的 JS 新增了微信的一些 API 接口,并去除了一些不必要的功能(如 DOM)。
8.那么小程序和h5的网页到底有没有区别,有人会说,除了7里面说的差别,小程序的源码是托管在微信小程序后台的,而且限制小程序内置浏览器使用,最重要的是小程序是被打包成.wxapkg 的,使用时加载下载到本地。
9.众所周知h5实现的网页,是没有提供源码黑盒环境能力的,而android app和ios app 是可以通过商用加固软件来实现的。小程序从语言上像网页语言,从打包方式上更像android app和ios app,那么小程序能提供源码的黑盒环境吗?到这我想又有人会说了,小程序是腾讯亲儿子,虽然不允许三方加固软件介入,但是在小程序后台上传源码时自带打包加密,说的没错大家都是这么理解的,可事实不是这样的,如果真的是这样,估计大家也就看不到这篇文章了。小程序的包现在加密等级几乎没有,大多数包的源码文件是可以被反编译的。大家可以在网上搜索下小程序反编译工具,搜索结果还是很多的,先给大家上一个github上star数较高的工具链接:https://github.com/qwerty472123/wxappUnpacker
使用教程地址:https://blog.csdn.net/as66708/article/details/80618978

基于以上的前提说明,才引出我们今天的话题,如何基于安全的前提下实现小程序授权登录并绑定自有账户体系,下面我们来聊一下思路
二、方案思考
1.先来思考三个问题
1).如何授权获取手机号?
目前小程序获取微信绑定手机号的功能,只能认证过的机构号才能用,个人及非认证过的机构号是不能用的,而且是前端授权回调实现。获取手机号具体方法:
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getPhoneNumber.html
2).小程序授权登录是啥?
小程序登录:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html(不包含手机号即无法完成自有账号体系绑定)
3).如何依赖小程序授权接口获取的用户微信绑定手机号实现自有账号体系的绑定?
2.梳理流程
1)我们再来看一下小程序授权登录的流程
在这里插入图片描述
我们来看一下服务端与小程序的数据交互接口https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html,该接口返回数据,明确手机号为用户隐私数据,不予返回,唯一获取方法请详情参考1.1)获取手机号具体方法
那么问题来了,如果依赖小程序的登录来实现我们的数据合法性验签,只要接口返回用户手机号,添加前端用户授权登录后,我们就可以在第步实现完成自有账户体系登录及注册流程,但是现在微信服务端api以用户隐私为由没有返回用户手机号,把这个头疼的问题扔给了开发者,我们此处完成不了用户openid 和自有账户的绑定(受影响业务:第一次从小程序登录的老用户,新注册的用户),也就没有后续⑤处的自有账户体系自定义登录状态。继续~
2)小程序获取微信绑定手机号流程
a)插播科普下微信开放数据获取流程https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/signature.html#method-cloud
在这里插入图片描述

b)小程序前端获取用户手机号流程
在这里插入图片描述
简单的画了下流程,我们可以看到②❸处是前端获取手机明文的过程,那么如何用手机号和openid完成自有账号体系绑定(注册和登录时openid绑定)呢?有人可能会说流程图中不就是完成自有账户体系的绑定过程吗?那么问题又来了,的实现方式我们就不解释了,参考前提说明,服务端不相信非黑盒环境下前端传入的数据。那如果我们把❸❹ 整合实现组合服务呢,我们来看下解密后的数据

{
    "phoneNumber": "13580006666",//用户绑定的手机号(国外手机号会有区号)
    "purePhoneNumber": "13580006666",//没有区号的手机号
    "countryCode": "86",//区号
    "watermark":
    {
        "appid":"APPID",
        "timestamp": TIMESTAMP
    }
}

不难发现,这里面没有小程序的openid,这里又有人会说你自己传进来就好了,那么这里因为encryptedData是有三方加密验签的我们默认数据可靠(流传中返回数据格式现在已经有大手可以模拟,个人存怀疑态度,后面所写先基于它是安全的),那我们如何来保证openid不是大手前端模拟传入呢?其实大家细想一下的服务端解密是建立小程序登录流程上的,服务端要获取session_key,在获取session_key 的时候我们已经获取openid+session_key的对应关系并缓存在服务端缓存服务器上(有可能失效),其实依赖解密接口,如果解密成功,正好有效的间接验证码了openid的和手机号的有效对应关系。细想这是一个可行方案,我们可以在自己的后端服务器上提供解密和小程序登录组合服务(自用账户体系快捷登录/注册接口)这样我们通过微信自有的验签拿到了用户的手机号和openid,完成自有账户体系的绑定后返回自有系统的token到前端,问题就解决了。

注意:在②回调中调用 wx.login() 登录,可能会刷新登录态。此时服务器使用 code 换取的 sessionKey 不是加密时使用的 sessionKey,导致解密失败。建议开发者提前进行 login;或者在回调中先使用 checkSession 进行登录态检查,避免 login 刷新登录态。

三、方案总结
  小程序授权登录流程并不能满足自有手机号账户系统的自定义登录状态,即登录流程中的⑤返回自定义登录状态。因为我们此处不考虑不用手机号创建的自有账号体系临时账号(后期合并用户数据是坑),那么在用户绑定了微信手机号且授权使用的情况下,我们可以提供组合接口,依赖wx.login 获取的open_id 和session_key,和微信的验签规则实现获取合法的openid 和手机号完成自有账户体系的快捷登录注册。
在这里插入图片描述

上图为最终版实现流程,以上为个人思路,欢迎大家给出建设性意见,不喜勿喷,谢谢。

参考文档
小程序官方文档:https://developers.weixin.qq.com/miniprogram/dev/framework/
问答帖:https://zhidao.baidu.com/question/493600128941309572.html
工具帖:https://blog.csdn.net/as66708/article/details/80618978
同事:longer

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值