小程序登录态管理的方法示例

所谓的登录态其实就是客户端发送请求的时候携带的token(通常叫做令牌),当用户输入账号密码,验证成功之后,服务端生成一个token传递给客户端,客户端在后续的请求中携带这个token,服务器进行校验,校验成功则处理客户端的请求,校验失败则要求客户端重新去登陆。

在web项目中,我们通常使用session来管理这一过程。

客户端首次访问请求的时候,服务端返回一个sessionId作为cookie给客户端,往后客户端每次请求都带上这个cookie与服务端进行通信,当执行完登陆操作以后,服务端将用户数据存入到session中;随后的每次请求,服务端都从cookie中取出sessionId,利用sessionId去查询session,利用session中是否含有用户信息来判断用户是否有登陆。

关于cookie与session的关系,请先看笔者之前的一篇文章:浅谈cookie和session

一.小程序的登录态

要明白小程序跟传统的web项目的不同之处在于它不依托于浏览器,所以它没有cookie,自然无法用session来管理登录态。这给我们的编码造成了不小麻烦。但是其实我们可以通过在请求头中加入键为JESSIONID(或者SESSION),值为sessionId的cookie来模拟这种操作。同时在服务端响应给小程序的时候,若sessionId有发生变化则再回传给客户端。

还有一个要注意的是,小程序也有自己的登录态,那就是session_key的生命周期,session_key是小程序中为了加密数据而提供的一个密钥,具有一定的生命周期。查看小程序官方文档,可以知道它是在服务端调用code2Session获取的。可以通过小程序的wx.checkSession()来校验小程序端的登录态是否过期。

弄清楚了上述两点,我们的要解决的问题包括。

1.校验小程序的登录态

2.校验服务端的登录态,即是否能从session中拿到用户数据。

3.任何一方的登录态过期,都调用登陆的相关代码,注意登陆的相关代码包含小程序端和服务端。后续会说。

4.用户信息如何储存。在web项目里,我们是将用户信息存放在session里,这样在服务端就可以直接用,而借助jsp的某些标签,在jsp页面我们也可以直接从session中拿出用户数据。但现在是小程序,在服务端我们依然可以从session中获取用户数据,但是在客户端,必须等待服务端的回传。这样每次请求都响应用户数据的做法显然不是很合理的,所以我们可以将用户数据保存在微信的缓存里。

5.拦截器问题,在web项目中,我们会在服务端给每个controller写拦截器,拦截器一般是判断登录态,判断成功则执行controller中的代码,失败的话,我们一般会重定向到登陆页面,或者执行完登陆代码后重定向到某个特定页面(微信站中这样做的)。但是这种做法在小程序中是无效的,小程序是动静分离的,我们不可能从服务端去重定向到小程序的特定页面,也不可能从服务端去调用小程序的wx.login()方法。所以,我们把这种拦截校验的发起从服务端移到小程序端。让小程序主动发起这种校验,也就是第二点的检查服务端登录态。

二.小程序登录态的方案

经过上面的分析,我们整理出小程序登录态的方案。

1.在需要用户登录态的页面,首先从缓存中获取用户数据userInfo,若无数据,则跳4

2.调用wx.checkSession()检查小程序端的登录态是否过期,若没过期,跳3,若过期,跳4

3.调用服务端的代码检查session是否过期(即检查服务端的登录态),若没过期则拿到用户数据继续执行后续的操作。若过期,则跳4.

4.登录操作,登录操作分为如下几个步骤。

--a.小程序端调用wx.login()接口得到code。(code只能使用一次)

--b.服务端利用这个code访问code2Session接口得到session_key和open_id,并将session_key和open_id存入到session中。

--c.服务端执行登录操作,主要是通过open_id去数据库中寻找用户数据,若无则新增用户到数据库,若有则取出用户数据。

--d.将用户数据userInfo,session_key,open_id等数据都存放到session中,方便服务端下次拿。

--e.将用户数据userInfo,连同session的sessionId一起响应给小程序端。

--f.小程序端得到用户数据和userInfo后更新缓存中的userInfo(包括JESSIONID的值sessionId)

上述过程可以用微信官方的这张图来表示。

小程序登录态管理的方法示例

这边的自定义登录态就是sessionId,自定义登录态与session_key,openid关联就是将session_key,openid存入到session中。

下面我们来看具体的代码吧。

1.因为很多页面需要取到用户的数据才能继续操作,所以我们在app.js里面写一个getUseInfo方法,供各子页面调用,方法如下。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/966925be8e7c088bb5494496df7fef4e.html