舟山闪爸电子技术有限公司

微信小程序模擬cookie的實(shí)現(xiàn)

大部分的微信小程序不支持cookie,那么微信小程序模擬cookie的實(shí)現(xiàn)要如何開發(fā),下面為大家?guī)砦⑿判〕绦蚰Mcookie的實(shí)現(xiàn)過程。

微信小程序模擬cookie的實(shí)現(xiàn)

開發(fā)背景

現(xiàn)有系統(tǒng)已經(jīng)有一套完整的接口,用戶狀態(tài)、驗(yàn)證都是基于 cookie 的。

部分業(yè)務(wù)要上小程序版本,眾所周知,微信小程序不支持 cookie 的。要上線的業(yè)務(wù),最好的方式還是基于現(xiàn)有這套接口做,改動(dòng)不大,也最快。

模擬 cookie

通過瀏覽器的開發(fā)工具,Network 欄查看請求,瀏覽器中的 cookie 會(huì)攜帶在每個(gè) http 的 Request Headers 里面,用 Cookie 作為鍵名。

那么,在微信官方請求方式 wx.request 中,我們設(shè)置 header,添加一個(gè) Cookie 應(yīng)該可以得以模擬。

問題又來了,怎么獲取到服務(wù)器返回的 cookie 呢。

通過登錄接口(登錄的時(shí)候,服務(wù)器端會(huì)植入 cookie 作為 session),查看 http 返回頭。

wx.request({
    url: '/api/login',
    success: (data) => {
        if(data.statusCode === 200) {
            console.log(data);
            // data 中應(yīng)該會(huì)有 Set-Cookie 或 set-cookie 的字樣,嗯,那就是服務(wù)器種下的 cookie
        }
    }
})

拿到 cookie 存入本地中,下次請求數(shù)據(jù)的時(shí)候直接塞進(jìn)去,完美。

格式化 cookie

原本以為 cookie 只需要一進(jìn)一出就可以完美模擬,實(shí)際操作才發(fā)現(xiàn),攜帶上去的 cookie 服務(wù)器無法識(shí)別。

服務(wù)器返回的 cookie 中,會(huì)攜帶上很多儲(chǔ)存用的字段,例如 path=/;

// 服務(wù)器放回的 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,imgUrl=; Path=/; Expires=Thu, 21 Jun 2018 13:15:08 GMT';

// 模擬的是需要的格式樣式
let virtualCookie = 'userKey=1234567890; userName=111111; userId=111;';

媽耶~要怎么過濾呢。

簡單粗糙的寫了一個(gè)過濾方案。

// cookie 的本地存儲(chǔ)位置
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=/; 在某些應(yīng)用下會(huì)是 path=/;

normalizeUserCookie 主要是過濾了 xx=xxx; 這樣的數(shù)據(jù),然后排除 path=/; 這樣無意義的數(shù)據(jù)。

在登錄接口的時(shí)候,存上 cookie,在接下來的請求中帶上,那么,應(yīng)該、沒錯(cuò)、可能、可以模擬了。

配合 Egg.js

Egg 內(nèi)置的 egg-security 插件默認(rèn)對所有『非安全』的方法,例如 POST,PUT,DELETE 都進(jìn)行 CSRF 校驗(yàn)。

Egg.js 雖然可以在配置中關(guān)閉 CSRF,但是,如果一定要使用呢?

首先,要弄明白一件事,csrfToken 怎么來的。

經(jīng)過多次驗(yàn)證得知,當(dāng) http 請求時(shí),在約定位置沒有攜帶上 csrfToken 值,此次請求會(huì)在返回的 cookie 中攜帶上一個(gè)新的 csrfToken;當(dāng)本次請求已攜帶上值,就不會(huì)產(chǎn)生成 csrfToken。當(dāng)約定位置帶上的 csrfToken 與 cookie 里面的 csrfToken 一致時(shí),通過驗(yàn)證。

接上面的 格式化用戶需要的 cookie 操作,先拋開 csrfToken 單獨(dú)處理用戶狀態(tài)等。

在每次請求結(jié)束后,試著單獨(dú)拿 cookie 中可能存在的 csrfToken,有值就緩存,沒值跳過用舊值。

封裝一個(gè) Ajax

本次小程序是基于 wepy 的,所以使用了優(yōu)化后的 wepy.request;

基于 Egg.js 的版本。

可能與實(shí)際開發(fā)有點(diǎn)出入,適當(dāng)修改。

import wepy from 'wepy';

export const HTTP_HOST = 'http://127.0.0.1:3000';

export const HTTP_HOST_API = `${HTTP_HOST}/api/wxmp`;

// cookie 的本地存儲(chǔ)位置
const COOKIE_KEY = '__cookie_key__';
// csrfToken 的本地存儲(chǔ)位置
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
 * 不一定每次請求都會(huì)更新 cookie
 * @param {String} cookie
 */
const seveCsrfTokenCookie = (cookie) => {
    if (cookie) {
        wx.setStorageSync(CSRF_TOKEN_KEY, cookie);
    }
};

/**
 * 請求數(shù)據(jù)
 * @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};`);

        // 設(shè)置請求頭部
        opt.header = Object.assign(
            {
                'x-csrf-token': csrf,
                Cookie: Cookies.join(' ')
            },
            opt.header || {}
        );
        opt.success = (data) => {
            seveCsrfTokenCookie(data.header['set-cookie']);
            // 統(tǒng)一操作
            if (data.statusCode == 200) {
                if (url === '/login') {
                    normalizeUserCookie(data.header['set-cookie']);
                }
                resolve(data.data);
            } else {
                reject('未知錯(cuò)誤,請重試一次');
            }
        };
        opt.fail = (err) => {
            reject(err);
        };
        opt.url = `${HTTP_HOST_API}${opt.url}`;
        wepy.request(opt);
    });
};

微信小程序模擬cookie的實(shí)現(xiàn)


【本站聲明】
  1、本站文章中所選用的圖片及文字來源于網(wǎng)絡(luò)以及用戶投稿,由于未聯(lián)系到知識(shí)產(chǎn)權(quán)人或未發(fā)現(xiàn)有關(guān)知識(shí)產(chǎn)權(quán)的登記,如有知識(shí)產(chǎn)權(quán)人并不愿意我們使用,如果有侵權(quán)請立即聯(lián)系。
  2、本網(wǎng)站不對文章中所涉及的內(nèi)容真實(shí)性、準(zhǔn)確性、可靠性負(fù)責(zé),僅系客觀性描述,如您需要了解該類商品/服務(wù)詳細(xì)的資訊,請您直接與該類商品/服務(wù)的提供者聯(lián)系。


KESION 科汛軟件

KESION 科汛軟件是國內(nèi)領(lǐng)先的在線教育軟件及私域社交電商軟件服務(wù)提供商,長期專注于為企業(yè)提供在線教育軟件及社交電商SaaS平臺(tái)解決方案。
公司核心產(chǎn)品云開店SaaS社交電商服務(wù)平臺(tái)、在線教育SaaS服務(wù)平臺(tái)、教育企業(yè)數(shù)字化SaaS云平臺(tái)、企微營銷助手、私有化獨(dú)立部署品牌網(wǎng)校和在線教育咨詢等。

KESION 不斷通過技術(shù)創(chuàng)新,提供產(chǎn)品和服務(wù),助力企業(yè)向數(shù)字化轉(zhuǎn)型,通過科技驅(qū)動(dòng)商業(yè)革新,讓商業(yè)變得更智慧!



▼點(diǎn)擊進(jìn)入科汛官網(wǎng)了解更多



熱門標(biāo)簽
微信小程序 SaaS
上/下篇
  • 微信小程序電商模板,微信電商小程序開發(fā)

  • 小程序——帶參返回上一頁幾種方法

換一換相關(guān)推薦
精選內(nèi)容
熱點(diǎn)精選