微信小程序踩坑-Cookie登陆失败_四袋粉的博客-CSDN博客_set-cookie 微信小程序不生效

目录

1 问题描述

小程序成功登陆后,安卓用户预约操作时,偶尔会出现登陆异常情况。

2 登陆实现方案

后端Cookie校验用户登陆状态

3 排查过程

1)后台日志排查,用户Cookie无效

2)微信小程序日志排查,安卓用户有问题

3)现象复现,安卓手机提示异常

4)微信小程序埋点输出日志,Cookie存取正常

5)正常与异常Cookie对比,Cookie顺序不对

6)异常Cookie排查,Cookie拼接不正确

4 为什么苹果手机、部分安卓手机没有问题?

5 问题原因

腾讯小程序Bug,Set-Cookie逗号拼接方式有问题

6 解决方法

Cookie正则分割,分号重新拼接

7 标准答案

8 硬广告

微信预约小程序,14天免费使用

1 问题描述
最近有用户反馈,小程序登陆有问题

小程序成功登陆后,安卓用户预约操作时,偶尔会出现登陆异常情况。
之前解决过shiro登陆失败的问题,《Shiro框架Given final block not properly padded问题解决》,但是没有彻底解决登陆失败的问题。

登陆失败现象极其诡异,问题难以复现。

1 用户10秒前刚登陆,用户后续操作马上提示“登陆异常”

2 部分安卓用户在登陆后,在后续操作提示“登陆异常”,这种现象是偶然发生的,安卓用户出现登陆异常概率大概是10分之1。

2 苹果用户从未没有出现”登陆异常“现象。

 

 

2 登陆实现方案
在介绍问题前,本文先简单描述下本文应用登陆实现方案。

本文的小程序应用是单独使用Cookie来维护登陆状态,登陆并未使用小程序的sessionKey来维护后台登陆状态。

后端Cookie校验用户登陆状态
为什么不使用小程序SessionKey维护登陆状态?

1 老应用有单独Cookie登陆方式。

2 后台支持多平台登陆(比如小程序、h5网页等),不完全依赖小程序SessionKey完成登陆 。

Shiro控制用户权限

 

1 获取微信小程序code值

2 code值以及appId换取用户openId

3 openId快捷登陆

4 小程序保存登陆Cookie

5 小程序携带Cookie请求后端应用

6 后端根据前端的Cookie校验用户的登陆情况

 

可惜小程序不支持Cookie,(浏览器一般会保存用户Cookie,方便后续浏览网页使用)

如何解决小程序支持Cookie登陆?

以下是网上常见的Cookie登陆解决方式。

// 登录
wx.login({
success: function (res) {
log.info(res)
//获取登录的临时凭证
var code = res.code;
//调用后端,获取微信的session_key,secret
wx.request({
url: domain + ‘/user/wxLogin’,
header: {
“Content-Type”: “application/x-www-form-urlencoded”
},
method: “POST”,
data: util.json2Form({
code: code,
appId: that.globalData.appId
}),
success: function (result) {
// cookie存储起来
var cookie = result.header[‘Set-Cookie’]
wx.setStorageSync(‘cookie’, cookie)

},
fail: function (res) {

}
})
}
})
})
wx.request从res.header[‘Set-Cookie’]中获取cookie信息,并使用wx.setStoargeSync将cookie信息同步写入小程序私有存储空间中

wx.request({
url: domain + ‘/api/xxx/xxx’,
header: {
“Content-Type”: “application/x-www-form-urlencoded”,
‘cookie’: wx.getStorageSync(“cookie”)
},
method: ‘POST’,
data: util.json2Form({ xx1: xx1, xx2: xx2 }),
success: function (result) {

},
fail: function (res) {
log.info(“服务器异常:” + res)
wx.showToast({
title: ‘服务器异常’,
icon: ‘none’,
duration: 2000
})
}
})
wx.getStorageSync同步将cookie从小程序中取出,小程序携带该cookie请求后台服务,完成用户登陆状态校验。

 

3 排查过程
问题不可怕,可怕的是不能稳定地复现case。本人平时使用iphone手机,重复用户的操作,基本复现不出来“登陆异常”的现象,只能在服务后台以及小程序前端疯狂埋点打日志。

1)后台日志排查,用户Cookie无效
从后台日志可以看出,用户成功登陆,但是用户没有在后续的请求使用用有效cookie去请求后台服务,后台直接拒绝服务。

 

2)微信小程序日志排查,安卓用户有问题
通过后台和小程序日志发现,出现“登陆异常”的用户基本是安卓用户,苹果用户基本没有这个问题。

 

3)现象复现,安卓手机提示异常
目标锁定安卓手机,直接找了台安卓手机,重复登陆、预约操作,大概反复操作10次,终于复现了“登陆异常”的现象,喜大普奔啊。

 

4)微信小程序埋点输出日志,Cookie存取正常
起初怀疑wx.setStoargeSync有bug,未将cookie成功写入小程序。

验证方式:将res.header[‘Set-Cookie’]、wx.getStorageSync日志输出。

如果res.header[‘Set-Cookie’]输出日志为空,则定位是后端服务问题,未将cookie携带返回。

如果res.header[‘Set-Cookie’]输出日志不为空,wx.getStorageSync(‘cookie’)输出日志为空,则定位setStorageSync写入有bug

但是最终现象res.header[‘Set-Cookie’]、wx.getStorageSync(‘cookie’)输出日志均不为空,排查思路中断了。

 

5)正常与异常Cookie对比,Cookie顺序不对
对比正常请求的cookie与异常请求的cookie

发现cookie的顺序不一样

后台shiro做权限控制,返回3个Set-Cookie值,苹果用户的请求基本是以JESSIONID开头,而有问题的安卓用户请求是以remeberMe=Delete开关

 

 

6)异常Cookie排查,Cookie拼接不正确
将登陆异常请求的cookie按照正常请求cookie的顺序调整了下, 用户请求后端可以成功登陆。

使用错误顺序cookie请求后端,后端解析cookie并未获取到JESSIONID。

后端是如何解析Cookie,根据分号”;”分割Cookie字符串,由于错误顺序Cookie是使用逗号做分割符,后端将Expires与JESSIONID视为一个整体,所以无法解析出JESSIONID

 

4 为什么苹果手机、部分安卓手机没有问题?
没有问题的Cookie,JESSIONID可以被后台正确分割出来。苹果手机获取Set-Cookie顺序是严格一致的,安卓手机Set-Cookie顺序是随机的。

 

5 问题原因
腾讯小程序Bug,Set-Cookie逗号拼接方式有问题
微信开放社区也有人反馈过这个bug,但是以微信社区人员解决问题的稀烂态度,至今未解决该bug。

解决bug只能靠自己去兼容这个bug

 

 

6 解决方法
当返回结果的header有多个Set-Cookier时,微信小程序获取res.header[‘Set-Cookie’],已经是将Set-Cookie用逗号拼接好的字符串。

如果使用简单的逗号分割,Expires时间也含有逗号,Cookie结果是错误的。

Cookie正则分割,分号重新拼接
见示例

 

简单的逗号无法分割,可以使用正则表达式去分割Cookie字符串,

需要被分割的逗号,后继字符串是含有=

 

7 标准答案
微信小程序使用Cookie登陆标准答案

// 登录
wx.login({
success: function (res) {
log.info(res)
//获取登录的临时凭证
var code = res.code;
//调用后端,获取微信的session_key,secret
wx.request({
url: domain + ‘/user/wxLogin’,
header: {
“Content-Type”: “application/x-www-form-urlencoded”
},
method: “POST”,
data: util.json2Form({
code: code,
appId: that.globalData.appId
}),
success: function (result) {
// Set-Cookie字符串获取
var cookie = result.header[‘Set-Cookie’]
// 字符串分割成数组
var cookieArray = cookie.split(/,(?=[^,]*=)/)
// 分号拼接数组
var newCookie = cookieArray.join(‘;’)
// 存储拼接后的cookie
try {
wx.setStorageSync(‘cookie’, newCookie)
} catch (error) {
log.error(‘setStorageSync cookie fail’)
}

},
fail: function (res) {

}
})
}
})

————————————————
版权声明:本文为CSDN博主「四袋粉」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/czx0132/article/details/110101854

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏