微信小程序登录态控制深入分析


Posted in Javascript onApril 12, 2017

微信小程序登录态控制深入分析

最近微信小程序终于开放了个人注册,我当然不能浪费这个炫技的好机会,“菲麦日程”小程序正在全力推进中,尽请期待~~
在登录态控制中,摸索尝试了小一阵子,特此分享

一、微信建议的登录态控制

微信小程序登录态控制深入分析

说明:

1)小程序内通过wx.login接口获得code
2)将code传入后台,后台对微信服务器发起一个https请求换取openid、session_key
3)后台生成一个自身的3rd_session(以此为key值保持openid和session_key),返回给前端。

PS:微信方的openid和session_key并没有发回给前端小程序

4)小程序拿到3rd_session之后保持在本地
5)小程序请求登录区内接口,通过wx.checkSession检查登录态,如果失效重新走上述登录流程,否则待上3rd_session到后台进行登录验证

二、可不可以不接受它的建议

不是我反骨,而是我的微信小程序不需要获取什么私密数据,用不到session_key,只需要一个openid,微信特别强调了,为了自身应用安全,session_key 不应该在网络上传输,可没说不可以传输openid,那么如果我将openid直接返回给前端小程序,会不会方便很多?下面我们来具体分析下:

永不过期的openid:

要知道,session_key有过期时间,必须适时重新获取,而针对每一个小程序,唯一标识用户的openid可不会过期,如果只在用户第一次登录的时候,通过后台请求到openid,小程序缓存到本地,之后每次请求都以这个openid作为唯一凭证,岂不是一本万利~~

事实上,上面的做法忽略了一个致命的问题,手机上是可以切换微信账户的,如果手机I上原先登录了账户A,已经保存了用户A的openid,有一天手机I上切换到了账户B上,小程序检测到openid存在,并不会重新获取openid,那么账户B就请求到了账户A的数据,这就造成数据乱象了

登录态过期后重新获取openid:

上述的问题并不能打消我使用openid作为登录凭证的念头,只需要稍作改进,数据就不会乱窜:每次进入小程序通过wx.checkSession检测登录是否失效,如果失效重新获取openid,要知道,手机切换了登录账号,登录态一定会过期,这样虽不能一本万利,但也足够省心。

这个时候应该有一个然而,以永不过期的openid作为登录凭证,并不是明智之举,一旦被人截获,就再也没有翻身的机会了,而维护一个第三发的session,至少拥有有效期,这在很大程度上增加了安全性。并且,现在不需要使用session_key,不代表以后,保持系统的可扩展性,才能以不变应万变

事实证明,我还是应该接受它的建议

三、基于redis维护3rd_session

维护3rd_session需要一个内存数据库,这里我选用了redis

维护会话态是内存数据库的典型应用场景,毕竟量小,并且要求速度快,这么一个小应用,当然也可以自己在内存中维护一个对象来进行会话id的处理,但是肯定难以跟一个成熟的系统相媲美

抛开代码实现,这似乎就是一句话可以概括的事情,生成一个唯一的随机串sessionid,以此为key,openid和微信方的session_key为value存入redis,并把sessionid传回给客户端。

但是,翻遍小程序的官方文档,除了一句据说的wx.checkSession对开发者来说是透明的,并没有小程序登录态何时过期的具体说明,如何才能同步前后端的会话过期时间呢?

四、前后端会话过期时间同步

一开始,我还是试图寻找小程序的登录态时效

{"session_key":"...","expires_in":7200,"openid":"..."}

在code2session接口返回的数据中,有一个可疑的字段expires_in,它的值是7200,似乎存储到redis中的sessionid设置为7200就可以同步了。可是实践的结果再次让人失望,不管是设置成7200还是60*60*24(一天),都出现了小程序会话尚在有效期,而服务器端会话已经过期的情况,这直接导致了小程序带着已经缓存的sessionid到服务器端请求接口,返回未登录的情况

看来还是只有wx.checkSession才知道小程序会话啥时候过期,于是,作战方案重新做了调整,如果wx.checkSession检测到会话失效,那么带上已经缓存在本地的sessionid(如果有的话),重新发起登录请求,后台从code2session中拿到新的请求结果后,生成新的随机sessionid并入库reids,并且把老的sessionid移除(如果有的话)

当然不移除也不会带来什么功能上的影响,但是会存在两个问题,首先,跟使用open_id作为登录凭证一样,旧的sessionid永不过期,其次,无用的session数据占用redis资源,会拖垮访问性能

五、“脱贫致富指数”统计

我给小程序的用户数安了一个高大上的名字“脱贫致富指数”,纯属娱乐,切勿当真

为了统计使用小程序的用户数,需要一个表来保存用户数据,后台提供一个接口,让小程序将用户数据传上来进行一个注册操作,当然可以把这个功能合并到登录接口上,每次登录都把前端小程序获得的微信用户数据带上,如果发现数据库中还没有该用户的信息,则进行入库操作

不难发现,其实只需要用户第一次登录的时候注册一次就行了,所以上述方法虽然简便,但是有点浪费带宽,所以应该额外提供一个注册接口,登录接口只需要返回一个用户是否已经注册的标志,让客户端决定是否需要获取用户信息,进行注册操作(当然后台也不会让同一个用户重复入库)

那么问题就变成如何判断用户是第一次登录了:

1)判断登录请求中有没有带上sessionid,如果没带上,肯定是第一次登录;如果带上了就是登录过的用户?不,别忘了,前面说过,用户可能会在同一设备切换账户,那就有可能在登录接口中带上了别人sessionid,那并不能表明用户曾经登录过

2)通过带上来的sessionid从redis中拿到openid,跟在code2session新请求到的openid进行比对,如果一致,可以证明用户曾经登录过,否则,仍需要用户进行注册

总结

时间是浪费了那么一些,但是进过思考摸索,代码肯定更完备了~~

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Javascript 相关文章推荐
表单的焦点顺序tabindex和对应enter键提交
Jan 04 Javascript
Extjs中ComboBoxTree实现的下拉框树效果(自写)
May 28 Javascript
Javascript小技巧之生成html元素
May 15 Javascript
jQuery select表单提交省市区城市三级联动核心代码
Jun 09 Javascript
node.js中的http.response.setHeader方法使用说明
Dec 14 Javascript
javascript进行四舍五入方法汇总
Dec 16 Javascript
详解 javascript中offsetleft属性的用法
Nov 11 Javascript
react-native 完整实现登录功能的示例代码
Sep 11 Javascript
JavaScript闭包原理与用法实例分析
Aug 10 Javascript
在vue中获取token,并将token写进header的方法
Sep 26 Javascript
在vue+element ui框架里实现lodash的debounce防抖
Nov 13 Javascript
vue路由权限校验功能的实现代码
Jun 07 Javascript
JavaScript数据结构之二叉查找树的定义与表示方法
Apr 12 #Javascript
微信小程序微信支付接入开发实例详解
Apr 12 #Javascript
JavaScript数据结构之广义表的定义与表示方法详解
Apr 12 #Javascript
JavaScript数据结构之数组的表示方法示例
Apr 12 #Javascript
easyui-edatagrid.js实现回车键结束编辑功能的实例
Apr 12 #Javascript
Vue生命周期示例详解
Apr 12 #Javascript
easyui关于validatebox实现多重规则验证的方法(必看)
Apr 12 #Javascript
You might like
自动生成文章摘要的代码[PHP 版本]
2007/03/20 PHP
浅析PHP程序防止ddos,dns,集群服务器攻击的解决办法
2013/06/18 PHP
destoon安装出现Internal Server Error的解决方法
2014/06/21 PHP
php实现的支持断点续传的文件下载类
2014/09/23 PHP
php+mysql+ajax 局部刷新点赞/取消点赞功能(每个账号只点赞一次)
2020/07/24 PHP
自适应图片大小的弹出窗口
2006/07/27 Javascript
一个分享按钮的插件使用介绍(可扩展,内附开发制作流程)
2011/09/19 Javascript
用jquery实现点击栏目背景色改变
2012/12/10 Javascript
js中的屏蔽的使用示例
2013/07/30 Javascript
Table冻结表头示例代码
2013/08/20 Javascript
为什么Node.js会这么火呢?Node.js流行的原因
2014/12/01 Javascript
jquery捕捉回车键及获取checkbox值与异步请求的方法
2015/12/24 Javascript
javascript嵌套函数和在函数内调用外部函数的区别分析
2016/01/31 Javascript
Bootstrap学习系列之使用 Bootstrap Typeahead 组件实现百度下拉效果
2016/07/07 Javascript
Bootstrap表单使用方法详解
2017/02/17 Javascript
Bootstrap缩略图的创建方法
2017/03/22 Javascript
浅析JS抽象工厂模式
2017/12/14 Javascript
JavaScript引用类型RegExp基本用法详解
2018/08/09 Javascript
vue中实现高德定位功能
2019/12/03 Javascript
vue+Element-ui实现登录注册表单
2020/11/17 Javascript
[01:02:02]DOTA2上海特级锦标赛A组败者赛 EHOME VS CDEC第二局
2016/02/25 DOTA
[40:55]Liquid vs LGD 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python基于回溯法子集树模板解决选排问题示例
2017/09/07 Python
Python爬虫天气预报实例详解(小白入门)
2018/01/24 Python
Python判断telnet通不通的实例
2019/01/26 Python
用Python画一个LinkinPark的logo代码实例
2019/09/10 Python
matplotlib常见函数之plt.rcParams、matshow的使用(坐标轴设置)
2021/01/05 Python
html5嵌入内容_动力节点Java学院整理
2017/07/07 HTML / CSS
专门出售各种儿童读物的网站:Put Me In The Story
2016/08/07 全球购物
小学生自我评价范例
2013/09/24 职场文书
2015元旦晚会主持词(开场白+结束语)
2014/12/14 职场文书
劳模事迹材料范文
2014/12/24 职场文书
团代会闭幕词
2015/01/28 职场文书
英语辞职信范文
2015/02/28 职场文书
公共场所卫生管理制度
2015/08/05 职场文书
科级干部培训心得体会
2016/01/06 职场文书