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


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 相关文章推荐
window.location和document.location的区别分析
Dec 23 Javascript
jQuery 技巧小结
Apr 02 Javascript
JS date对象的减法处理实现代码
Dec 28 Javascript
js中的this关键字详解
Sep 25 Javascript
jquery+CSS3实现3D拖拽相册效果
Jul 18 Javascript
javascript 实现动态侧边栏实例详解
Nov 11 Javascript
JS出现失效的情况总结
Jan 20 Javascript
JS实现弹出下载对话框及常见文件类型的下载
Jul 13 Javascript
微信小程序实现图片上传功能实例(前端+PHP后端)
Jan 10 Javascript
使用Angular CLI快速创建Angular项目的一些基本概念和写法小结
Apr 22 Javascript
element-ui循环显示radio控件信息的方法
Aug 24 Javascript
Vue实现小购物车功能
Dec 21 Vue.js
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如何开启Opcache功能提升程序处理效率
2020/04/27 PHP
js操作Xml(向服务器发送Xml,处理服务器返回的Xml)(IE下有效)
2009/01/30 Javascript
JS array 数组详解
2009/03/22 Javascript
jquery数组封装使用方法分享(jquery数组遍历)
2014/03/25 Javascript
jQuery1.9.1针对checkbox的调整方法(prop)
2014/05/01 Javascript
处理文本部分内容的TextRange对象应用实例
2014/07/29 Javascript
jquery操作复选框checkbox的方法汇总
2015/02/05 Javascript
IE下使用jQuery重置iframe地址时内存泄露问题解决办法
2015/02/05 Javascript
JQuery球队选择实例
2015/05/18 Javascript
javascript实现获取浏览器版本、浏览器类型
2015/12/02 Javascript
jQuery动态添加及删除表单上传元素的方法(附demo源码下载)
2016/01/15 Javascript
JS 实现Base64编码与解码实例详解
2016/11/07 Javascript
vuejs通过filterBy、orderBy实现搜索筛选、降序排序数据
2020/10/26 Javascript
详解vue表单——小白速看
2018/04/08 Javascript
ES6中定义类和对象的方法示例
2019/07/31 Javascript
微信小程序scroll-view实现滚动到锚点左侧导航栏点餐功能(点击种类,滚动到锚点)
2020/06/11 Javascript
Python排序算法实例代码
2017/08/10 Python
Python八大常见排序算法定义、实现及时间消耗效率分析
2018/04/27 Python
Python读取系统文件夹内所有文件并统计数量的方法
2018/10/23 Python
pyqt5 禁止窗口最大化和禁止窗口拉伸的方法
2019/06/18 Python
pyqt5 实现多窗口跳转的方法
2019/06/19 Python
Python 3.8正式发布重要新功能一览
2019/10/17 Python
python GUI库图形界面开发之PyQt5日期时间控件QDateTimeEdit详细使用方法与实例
2020/02/27 Python
汉森冲浪板:Hansen Surfboards
2018/05/19 全球购物
Omio英国:搜索并比较便宜的巴士、火车和飞机
2019/08/27 全球购物
办公室前台的岗位职责
2013/12/20 职场文书
一年级数学教学反思
2014/02/01 职场文书
求职信怎么写
2014/05/23 职场文书
本科应届生求职信
2014/08/05 职场文书
公司副总经理岗位职责
2014/10/01 职场文书
初三毕业评语
2014/12/26 职场文书
关于迟到的检讨书
2015/05/06 职场文书
2015年留守儿童工作总结
2015/05/22 职场文书
结婚十年感言
2015/07/31 职场文书
《7的乘法口诀》教学反思
2016/02/18 职场文书
2019财务管理制度最新范本!
2019/07/09 职场文书