微信小程序之登录态探索

作者:Gauch

https://segmentfault.com/a/1190000017042906

登录,几乎什么项目都会用到,其重要性不言而喻,而小程序的登录却一直是为人头疼的一件事,这里我分享下我们在小程序登录上的探索。

通常的登录都是通过一个表单,这很正常,但如果在小程序里你也这么做那就有点不可思议了,微信的一键登录对用户体验有多好你难道不知道?不用是不是脑子有坑?最主要你要利用微信的生态必须需要用微信的登录,以获取相关信息来和微信交互,OK,我们进入正题。

触发登录授权弹窗

用户在小程序、小游戏中需要点击组件后,才可以触发登录授权弹窗、授权自己的昵称头像等数据。

友情提示一下: wx.login 并不需要点击组件,需要的是 wx.getUserInfo,但通常我们都会用到 UnionIDencryptedDataiv 等信息完成完整的登录流程,本文主要聚焦的也是这种场景。

所以之前直接通过调用API的方式就行不通了,那么问题来了——这个点击按钮要放到哪里?

放到首页,一进小程序就必须先登录。这样显然很粗暴,而且问题并没有解决,反而会把用户直接拒之门外,毕竟你不是用小程序做后台系统,什么场景都需要授权,先授权也是必须的。

在需要授权的时候跳到登陆页面。这样就解决了上面遇到的不需要授权的时候也被强制授权,可是这样好吗?

体验上不好,操作被打断,尤其整个页面都不需要授权只有在一个地方需要授权的,例如:你正在读一篇文章,读罢深有感触,想评论一番,洋洋洒洒几十字写完正准备点击呢,他妈的跳转了!跳转了!

又一个漏斗,增加用户流失率。还TM要登录!很多用户心里一定这么想。

那就直接放在需要登录的页面上(这不是漏斗吗?很多读者一定这么想。但想想看上面那个场景,点评论时只是需要点击下弹出的登录按钮,而且还假模假样的以微信的口吻提醒你需要登录,那你会不会登录?最起码你很愿意登录,而且来的很突然,我控几不住自己的手就点了!点了!)。

可是这种方式有一个问题:怎么在需要的页面都能弹出登录按钮?

弹出登录按钮

应该很多人都能想到:抽离出组件,那怎么保证在需要的页面都有这个组件呢?错杀一千也不能放过一个!把登录组件集成到共用的父组件,然后在每个页面都使用。我也建议这么做,因为这个共用的父组件其实又很多用处,例如iPhoneX适配等。

等等,什么都准备好了,什么时候需要登录呢?XX,这个肯定是你自己控制的啦。嗯~好吧,我们来理一理。

校验是否需要鉴权

请求接口的时候,嗯~这是大家的共识。BOSS来了——怎么鉴权?

官方的这张图已经做了很详尽的说明,这里不做赘述。

但是看到 session_key 了吗?看到官方同时说的了吗?

所以问题又来了:怎么保证 session_key 的有效性?

session_key 的有效性

诚如上图:

1、要保证调用接口时后端 session_key 不失效,只能在每次调用前先使用 wx.checkSession 检查是否有效

2、实践中也发现 wx.checkSeesion 非常耗时,大约200ms,所以也不能每次接口调用前都使用 wx.checkSession 检查是否有效

3、同时要注意⚠️前端不能随便重新执行 wx.login,因为可能导致正在进行的其它后端任务 session_key 失效

天啦噜,怎么办?!通过实践和偶然的发现——官方的示例代码:

得知:在使用小程序期间session_key是不会失效的,so,你想到了什么?

1、在每个请求前去校验有效性

2、将校验有效性的结果存储起来

3、通过async/await和刚才存储起来的结果来保证不过多调用 wx.checkSession

先问个问题:你准备用什么方式来存储校验的结果?

让思考先飞一会。

storage吗?当然可以,不过不够完美,为什么?因为storage是永久的存储,而 session_key 的有效期却只是在使用小程序期间,所以你需要在小程序结束后手动重置该状态以重新校验其有效性,那是不是在app的onUnload里重置呢?不是!开发过小程序的应该都知道,那就是结束使用小程序的方式太多,不能保证每种方式都会触发onUnload,例如用户直接销毁了微信进程😳(其实你也可以在app的onShow里搞)那用什么呢?直接用内存啊,借助内存的自动管理来智能管理,所以最终代码应该是这样的:

// doRequest.js

let wxSessionValid = null // 微信session_key的有效性

// 带鉴权的请求封装

async function doRequestWithCheckAuth() {

 ...

 if (typeof wxSessionValid !== 'boolean') {

   wxSessionValid = await checkWxSession() // 检查微信session是否有效

 }

 if (!wxSessionValid) {

   await reLogin() // 重新登录

 }

 wxSessionValid = true // 重新登陆后session_key一定有效

 ...

}

这样是不是看起来比较完美了?嗯~

不知道有没有同学着急问业务侧的session(自定义的登录态)怎么没讲?嗯,那现在讲吧。

校验认证体系

怎么校验完整的认证体系?其实很简单,都不想把它作为一部分来讲,但既然讲了就必然有我想强调的:校验微信端的 session_key 略有麻烦,但不应该把它抛给服务端。

1、服务端不能直接校验 session_key 的有效性而是通过调用接口发现错误了才知道失效了,这是被动的

2、服务端需要同时维护两个session

而放在前端我们只需要校验两个session的有效性即可,任何一个失效就重新登录,这是积极主动有效的操作,应该被提倡。

贯通

OK,基本上梳理的差不多了,就差弹登录按钮了,这个简单,调用刚才封装的组件的方法就行了嘛,bingo,可是,点完允许后呢?怎么继续用户的操作呢?怎么能让用户的体验不被打断呢?先回放下刚才reLogin的代码:

async function reLogin() {

 // 确保有用户信息

 await new Promise(resolve => { // ⚠️注意开头有await!!!

   wx.getSetting({

     success: (res) => {

       // 如果用户没有授权或者没有必要的用户信息

       if (!res.authSetting['scope.userInfo'] || !_.isRealTrue(wx.getStorageSync('userInfoRes').userInfo)) {

         navToLogin(resolve) // 去提示用户点击登录按钮,⚠️注意:并把当前的resolve带过去

       } else {

         resolve() // 静默登录

       }

     }

   })

 })

 return new Promise((resolve) => {

   wx.login({

     success: res => {

       login(res.code).then((jwt) => {

         resolve(jwt) // resolve jwt

       }) // 通过code进行登录

     },

     fail(err) {

       wx.showToast({

         title: err.errMsg,

         icon: 'none',

         duration: 2000

       })

     }

   })

 })

}

function navToLogin(resolve) {

 /* eslint-disable no-undef */

 const pages = getCurrentPages()

 const page = pages[pages.length - 1] // 当前page

 page.openLoginModal(resolve) // 打开登录按钮弹框,并把当前的resolve带过去

}

上面的代码注释里有两个⚠️注意看到没?是的,通过回调的方式😂当用户同意授权了就继续余下的逻辑,如果被拒绝了,则安利他,再拒绝就终止操作,下次需要授权也会继续弹出授权。

关注公众号【grain先森】,回复关键词 【18福利】,获取为你准备的年终福利,更多关键词玩法期待你的探索~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容

  • 写在前面 微信小程序出来也蛮久了,经过了市场的考验,已经站稳脚跟,融入到了各行各业,市场需求激增打来的是开发人员的...
    月梦佳期阅读 1,689评论 1 1
  • 给提问的开发者的建议:提问之前先查询 文档、通过社区右上角搜索搜索已经存在的问题。 写一个简明扼要的标题,并且...
    极乐叔阅读 13,422评论 0 3
  • 背景 微信小程序的使用可以快速的基于场景进行用户圈的建立推广,其中根据业务需要使用用户信息以及授权过程,主要用到的...
    极乐叔阅读 1,178评论 1 4
  • 现在要讲的是小程序特有的一些API,可能会比较绕,不过本质是很简单的,只要按照步骤操作就会守得云开见日来 一.前言...
    梦想成为小仙女阅读 9,227评论 0 0
  • 每天陪着自己,爱着孩子,盼着老公,成了我生活的主旋律。如此平凡的世界。 一天中,我就是孩子的天。我在哪儿,孩子在哪...
    玉莹阅读 199评论 0 0