微信小程序模拟cookie的实现
本文摘要
大部分的微信小程序不支持cookie,那么微信小程序模拟cookie的实现要如何开发,下面为大家带来微信小程序模拟cookie的实现过程。 开发背景 现有系统已经有一套完整的接口,用户状态、验证都是基于cookie的。 部分业
大部分的微信小程序不支持cookie,那么微信小程序模拟cookie的实现要如何开发,下面为大家带来微信小程序模拟cookie的实现过程。
开发背景
现有系统已经有一套完整的接口,用户状态、验证都是基于cookie的。
部分业务要上小程序版本,众所周知,微信小程序不支持cookie的。要上线的业务,最好的方式还是基于现有这套接口做,改动不大,也最快。
模拟 cookie
通过浏览器的开发工具,Network栏查看请求,浏览器中的cookie会携带在每个http的Request Headers里面,用Cookie作为键名。
那么,在微信官方请求方式wx.request中,我们设置header,添加一个Cookie应该可以得以模拟。
问题又来了,怎么获取到服务器返回的cookie呢。
通过登录接口(登录的时候,服务器端会植入 cookie 作为 session),查看http返回头。
wx.request({
url: '/api/login',
success: (data) => {
if(data.statusCode === 200) {
console.log(data);
// data 中应该会有 Set-Cookie 或 set-cookie 的字样,嗯,那就是服务器种下的 cookie
}
}
})
拿到cookie存入本地中,下次请求数据的时候直接塞进去,完美。
格式化 cookie
原本以为cookie只需要一进一出就可以完美模拟,实际操作才发现,携带上去的cookie服务器无法识别。
服务器返回的cookie中,会携带上很多储存用的字段,例如path=/;
// 服务器放回的 cookie let cookie = 'userKey=1234567890; Path=/; Expires=Thu, 21 Jun 2018 13:15:08 GMT; HttpOnly,userId=111; Path=/; Expires=Thu, 21 Jun 2018 13:15:08 GMT,nickName=; Path=/; Expires=Thu, 21 Jun 2018 13:15:08 GMT,userName=111111; Path=/; Expires=Thu, 21 Jun 2018 13:15:08 GMT,Url=; Path=/; Expires=Thu, 21 Jun 2018 13:15:08 GMT'; // 模拟的是需要的格式样式 let virtualCookie = 'userKey=1234567890; userName=111111; userId=111;';
妈耶~要怎么过滤呢。
简单粗糙的写了一个过滤方案。
// cookie 的本地存储位置
const COOKIE_KEY = '__cookie_key__';
/**
* 格式化用户需要的 cookie
*/
const normalizeUserCookie = (cookies = '') => {
let __cookies = [];
(cookies.match(/([w-.]*)=([^s=]+);/g) || []).forEach((str) => {
if (str !== 'Path=/;' && str.indexOf('csrfToken=') !== 0) {
__cookies.push(str);
}
});
wx.setStorageSync(COOKIE_KEY, __cookies.join(' '));
};
csrfToken是接下来配合Egg.js用的,Path=/;在某些应用下会是path=/;
normalizeUserCookie主要是过滤了xx=xxx;这样的数据,然后排除path=/;这样无意义的数据。
在登录接口的时候,存上cookie,在接下来的请求中带上,那么,应该、没错、可能、可以模拟了。
配合 Egg.js
Egg内置的egg-security插件默认对所有『非安全』的方法,例如 POST,PUT,DELETE 都进行CSRF校验。
Egg.js虽然可以在配置中关闭CSRF,但是,如果一定要使用呢?
首先,要弄明白一件事,csrfToken怎么来的。
经过多次验证得知,当http请求时,在约定位置没有携带上csrfToken值,此次请求会在返回的cookie中携带上一个新的csrfToken;当本次请求已携带上值,就不会产生成csrfToken。当约定位置带上的csrfToken与cookie里面的csrfToken一致时,通过验证。
接上面的格式化用户需要的 cookie操作,先抛开csrfToken单独处理用户状态等。
在每次请求结束后,试着单独拿cookie中可能存在的csrfToken,有值就缓存,没值跳过用旧值。
封装一个 Ajax
本次小程序是基于wepy的,所以使用了优化后的wepy.request;
基于Egg.js的版本。
可能与实际开发有点出入,适当修改。
import wepy from 'wepy';
export const HTTP_HOST = 'http://127.0.0.1:3000';
export const HTTP_HOST_API = `${HTTP_HOST}/api/wxmp`;
// cookie 的本地存储位置
const COOKIE_KEY = '__cookie_key__';
// csrfToken 的本地存储位置
const CSRF_TOKEN_KEY = '__csrf_token__';
/**
* 清除用户Cookie
*/
export const cleanUserCookie = () => {
wx.setStorageSync(COOKIE_KEY, '');
}
/**
* 格式化用户需要的 cookie
* @param {String} cookies
*/
export const normalizeUserCookie = (cookies = '') => {
let __cookies = [];
(cookies.match(/([w-.]*)=([^s=]+);/g) || []).forEach((str) => {
if (str !== 'path=/;' && str.indexOf('csrfToken=') !== 0) {
__cookies.push(str);
}
});
wx.setStorageSync(COOKIE_KEY, __cookies);
};
/**
* 格式化 token
*/
const normalizeCsrfToken = () => {
let __value = wx.getStorageSync(CSRF_TOKEN_KEY) || '';
let __inputs = __value.match(/csrfToken=[S]*/) || [];
let __key = __inputs[0]; // csrfToken=1212132323;
if (!!!__key) {
return '';
}
// 脱水
return __key.replace(/;$/, '').replace(/^csrfToken=/, '');
};
/**
* 保存 csrf 的cookie
* 不一定每次请求都会更新 cookie
* @param {String} cookie
*/
const seveCsrfTokenCookie = (cookie) => {
if (cookie) {
wx.setStorageSync(CSRF_TOKEN_KEY, cookie);
}
};
/**
* 请求数据
* @param {Object} opt
*/
export const doAjax = (opt) => {
return new Promise((resolve, reject) => {
let Cookies = wx.getStorageSync(COOKIE_KEY) || [];
let csrf = normalizeCsrfToken();
let url = opt.url;
// 整理 Cookie
Cookies.push(`csrfToken=${csrf};`);
// 设置请求头部
opt.header = Object.assign(
{
'x-csrf-token': csrf,
Cookie: Cookies.join(' ')
},
opt.header || {}
);
opt.success = (data) => {
seveCsrfTokenCookie(data.header['set-cookie']);
// 统一操作
if (data.statusCode == 200) {
if (url === '/login') {
normalizeUserCookie(data.header['set-cookie']);
}
resolve(data.data);
} else {
reject('未知错误,请重试一次');
}
};
opt.fail = (err) => {
reject(err);
};
opt.url = `${HTTP_HOST_API}${opt.url}`;
wepy.request(opt);
});
};
第二部分:如何开通一个小商店
相关文章
****更多行业产品开发方案,请关注 加速度JSUDO***
<以上资讯仅供参考,如果您需解决具体问题,建议您关注作者;如果有软件产品开发需求,可在线咨询加速度产品经理获取方案和报价>
加速度JSUDO是一家企业级数字化解决方案提供商,专注于软件开发、网络营销、数字化转型咨询及云计算服务。核心业务包括定制化ERP/CRM系统、快速应用开发、大数据分析及物联网(IoT)解决方案,助力企业提升效率与智能化水平。服务覆盖制造业、零售、物流等多行业,致力于通过技术创新推动客户数字化转型。










