文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

微信小程序模拟cookie如何实现

2023-06-26 08:32

关注

本文小编为大家详细介绍“微信小程序模拟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=/;

// 服务器放回的 cookielet 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,imgUrl=; Path=/; Expires=Thu, 21 Jun 2018 13:15:08 GMT';// 模拟的是需要的格式样式let virtualCookie = 'userKey=1234567890; userName=111111; userId=111;';

妈耶~要怎么过滤呢。

简单粗糙的写了一个过滤方案。

// cookie 的本地存储位置const COOKIE_KEY = '__cookie_key__';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__';export const cleanUserCookie = () => {    wx.setStorageSync(COOKIE_KEY, '');}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);};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=/, '');};const seveCsrfTokenCookie = (cookie) => {    if (cookie) {        wx.setStorageSync(CSRF_TOKEN_KEY, cookie);    }};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);    });};

读到这里,这篇“微信小程序模拟cookie如何实现”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网行业资讯频道。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯