本文主要介绍微信小程序模拟cookie的实现。内容挺好的。现在分享给大家,给大家一个参考。
发展背景
现有系统已经有了一套完整的接口,用户状态和验证都是基于cookie的。
部分业务需要小程序版本。众所周知,微信小程序不支持cookie。要上线,最好的办法是基于现有的一套接口来做,改动小,速度最快。
模拟饼干
通过浏览器的开发工具Network bar检查请求,浏览器中的cookie会被携带在每个http请求头中,以Cookie为键名。
然后在微信的官方请求模式wx.request中,我们设置了头部,添加了一个Cookie,应该可以模拟。
问题又来了,如何获取服务器返回的cookie。
通过登录界面检查http返回头(登录时服务器会植入cookie作为session)。
wx . request({ URL:& # 039;/API/log in & # 039;,成功:(数据)= & gt{ if(data . status code = = = 200){ console . log(data);//数据中应该有Set-Cookie或者set-cookie这几个字。嗯,那是服务器植入的cookie)
获取cookie并将其存储在本地。下次请求数据时,只需插入即可。完美。
格式化cookie
原本以为只需进出就能完美模拟cookie,但实际操作发现其上搭载的cookie服务器无法识别。
服务器返回的cookie会携带很多存储字段,比如path =/;
//cookie让cookie被服务器放回= & # 039;userKey = 1234567890path =/;expires = 2018年6月21日星期四13:15:08 GMT;HttpOnly,userId = 111path =/;Expires=Thu,2018年6月21日13:15:08 GMT,昵称=;path =/;expires = 2018年6月21日星期四13:15:08 GMT,userName = 111111path =/;expires = 2018年6月21日星期四13:15:08 GMT,imgUrl =;path =/;expires = 2018年6月21日星期四13:15:08 GMT & # 039;;//模拟的是需要的格式样式let virtualCookie = & # 039userKey = 1234567890用户名= 111111;userId = 111';
妈~怎么过滤?
编写了一个简单的滤波方案。
//COOKIE常量COOKIE _ KEY = & # 039的本地存储位置;_ _ cookie _ key _ _ & # 039;/* * *用户所需的格式cookie */const normalize user cookie =(cookie = & # 039;')= & gt{ let _ _ cookies =[];(cookies.match(/([\\w\\-。]*)=([^\\s=]+);/g) || [])。forEach((str)= & gt;{ if (str!== 'path =/;'& amp& ampstr . index of(& # 039;csrfToken = & # 039) != = 0){ _ _ cookies . push(str);} });wx.setStorageSync(COOKIE_KEY,_ _ cookies . join(& # 039;'));};
CsrfToken接下来与Egg.js一起使用,Path =/;在某些应用中,它将是path =/;
NormalizeUserCookie主要过滤xx = xxx这样的数据,然后排除path =/;如此无意义的数据。
当登录到界面时,保存cookie并在下一次请求时带来。那么,应该是,是的,可能的,可以模拟的。
与Egg.js合作
默认情况下,egg -安全插件对所有“不安全”的方法执行CSRF验证,比如POST、PUT和DELETE。Egg.js在配置上可以关闭CSRF,但是如果一定要用呢?
首先要明白一件事,csrfToken是怎么来的。
经过多次验证,得知http请求时,约定位置没有携带csrfToken值,这个请求会在返回的cookie中携带一个新的CSRF令牌;当此请求已经包含值时,它将不会生成为csrfToken。当约定位置上的csrfToken与cookie中的csrfToken一致时,它被验证。
在上述格式化用户需求的cookie操作后,先丢弃csrfToken单独处理用户的状态等。
在每个请求的末尾,尝试单独获取可能存在于cookie中的csrfToken。如果有值,缓存它。如果没有值,则跳过使用旧值。
封装一个Ajax
这个小程序是基于wepy的,所以使用优化后的wepy.request
基于Egg.js的版本
可能和实际开发有点出入,适当修改一下。
从& # 039;导入wepywepy & # 039;导出常量HTTP _ HOST = & # 039http://127 . 0 . 0 . 1:3000 & # 039;;export const HTTP _ HOST _ API = ` $ { HTTP _ HOST }/API/wxmp `;//COOKIE常量COOKIE _ KEY = & # 039的本地存储位置;_ _ cookie _ key _ _ & # 039;csrf令牌常量csrf令牌_密钥的本地存储位置= & # 039;_ _ csrf _ token _ _ & # 039;/* * *清除用户COOKIE */export const clean user COOKIE =()= > { wx . setstoragesync(COOKIE _ KEY,& # 039;');}/* * *用户所需的格式cookie * @ param { string } cookie */export const normalize用户cookie =(cookie = & # 039;')= & gt{ let _ _ cookies =[];(cookies.match(/([\\w\\-。]*)=([^\\s=]+);/g) || [])。forEach((str)= & gt;{ if (str!== 'path =/;'& amp& ampstr . index of(& # 039;csrfToken = & # 039) != = 0){ _ _ cookies . push(str);} });wx.setStorageSync(COOKIE_KEY,_ _ cookies);};/* * *格式化TOKEN */constnormizecsrftoken =()= > { let _ _ value = wx . getstoragesync(CSRF _令牌_密钥)| | & # 039;';let _ _ inputs = _ _ value . match(/csrfToken =[\ \ S]*/)| |[];设_ _ key = _ _ inputs[0];//csrfToken = 1212132323;如果(!!!_ _ key){ return & # 039;';}//脱水返回_ _ key . replace(/;$/, '').replace(/^csrfToken=/,& # 039;');};/* * *用于保存csrf * Cookies的cookie可能不会在每次发出请求时更新* @ param { string } Cookies */constsvecsrftokencocookie =(cookie)= >;{ if(cookie){ wx . setstoragesync(CSRF _令牌_密钥,cookie);}};/* * * request data * @ param { object } opt */export const do Ajax =(opt)= >;{返回新承诺((解决,拒绝)= & gt{ let Cookies = wx . getstoragesync(COOKIE _ KEY)| |[];设csrf = normalizeCsrfToken();设url = opt.url//组织cookies cookies . push(` csrf token = $ { csrf };`);//设置请求头opt . header = object . assign({ & # 039;x-CSR F-令牌& # 039;:csrf,Cookie:cookies . join(& # 039;')},opt . header | | { });opt . success =(data)= & gt;{ seveCsrfTokenCookie(data . header[& # 039;set -cookie & # 039;]);//统一运算if(data . status code = = 200){ if(URL = = = & # 039;/log in & # 039;){ normalize user cookie(data . header[& # 039;set -cookie & # 039;]);} resolve(data . data);} else { reject(& # 039;未知,请重试& # 039;);} };opt . fail =(err)= & gt;{拒绝(错误);};opt . URL = ` $ { HTTP _ HOST _ API } $ { opt . URL } `;wepy . request(opt);});};
评论前必须登录!
注册