午夜91福利视频,午夜成人在线观看,午夜在线视频免费观看,午夜福利短视频,精品午夜成人免费视频APP

小程序模板網

微信小程序模擬 cookie

發布時(shi)間(jian):2018-06-21 10:27 所屬欄目:小程序開發教程

開發背景

現有系統(tong)已經有一套完整的(de)接(jie)口,用戶狀(zhuang)態(tai)、驗證(zheng)都是基(ji)于 cookie 的(de)。

部分業(ye)務要上(shang)小程(cheng)序版(ban)本,眾所周知(zhi),微信(xin)小程(cheng)序不(bu)支持 cookie 的(de)。要上(shang)線的(de)業(ye)務,最好的(de)方式(shi)還是基于(yu)現(xian)有這套接口做,改動不(bu)大,也最快。

模擬 cookie

通(tong)過(guo)瀏(liu)覽器的開發(fa)工(gong)具(ju),Network 欄查看請求,瀏(liu)覽器中的 cookie 會攜(xie)帶在(zai)每個 http 的 Request Headers 里面,用 Cookie 作為鍵名。

那么(me),在微(wei)信官方請求(qiu)方式(shi) wx.request 中,我們設置 header,添(tian)加(jia)一個(ge) Cookie 應該可(ke)以(yi)得(de)以(yi)模擬。

問(wen)題(ti)又來(lai)了(le),怎(zen)么獲(huo)取到服務器返回的(de) cookie 呢。

通過(guo)登錄接口(登錄的時(shi)候,服務器端會植入 cookie 作為 session),查看 http ;返回(hui)頭。

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

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

格式化 cookie

原本(ben)以為 ;cookie 只需(xu)要一進一出就可以完美模擬(ni),實際操作才發現,攜(xie)帶(dai)上去(qu)的(de) cookie 服務器(qi)無法識別。

服務器返回的(de) cookie 中,會攜帶上很多儲存用(yong)的(de)字段,例如 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,imgUrl=; Path=/; Expires=Thu, 21 Jun 2018 13:15:08 GMT';

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

媽耶~要怎么過濾(lv)呢。

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

// 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; 這(zhe)樣(yang)(yang)的(de)數(shu)據,然后排(pai)除 path=/; 這(zhe)樣(yang)(yang)無意義的(de)數(shu)據。

在登錄接(jie)口的時候,存上 cookie,在接(jie)下來的請求中帶(dai)上,那么,應(ying)該、沒錯、可(ke)能、可(ke)以(yi)模擬了(le)。

配合 Egg.js

Egg 內置的 egg-security 插件默認對所有『非安全』的方法,例如 POST,PUT,DELETE 都進行 CSRF 校驗。

Egg.js 雖(sui)然可以在(zai)配(pei)置中關閉(bi) ;CSRF,但(dan)是,如(ru)果一定(ding)要使用呢?

 首先,要弄明白(bai)一(yi)件事(shi),csrfToken 怎么來的。

經過多次(ci)驗證得知,當(dang) http 請(qing)求(qiu)時,在約定位置沒(mei)有攜帶上(shang) csrfToken 值(zhi),此次(ci)請(qing)求(qiu)會在返回的(de)(de)(de) cookie 中攜帶上(shang)一個(ge)新的(de)(de)(de) csrfToken;當(dang)本次(ci)請(qing)求(qiu)已攜帶上(shang)值(zhi),就(jiu)不會產生成 csrfToken。當(dang)約定位置帶上(shang)的(de)(de)(de) csrfToken 與 cookie 里面的(de)(de)(de) csrfToken 一致時,通過驗證。

接上面的 格式(shi)化用戶需(xu)要的 cookie 操作,先拋開(kai) csrfToken 單(dan)獨處理(li)用戶狀(zhuang)態等(deng)。

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

封裝一個 Ajax

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

基于 Egg.js 的版本(ben)。

可能(neng)與實際開發(fa)有點出入,適當修改(gai)。

import wepy from 'wepy';

export const HTTP_HOST = '//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);
    });
};


易優小程序(企業版)+靈(ling)活api+前(qian)后(hou)代(dai)碼開(kai)源 碼云(yun)倉庫:
本文地址://www.jinyoudianli.com/wxmini/doc/course/24577.html 復制鏈接 如需定制請聯(lian)系易優客服(fu)咨詢:

工作日 8:30-12:00 14:30-18:00
周六及(ji)部分節假(jia)日提供值班服務

易小優
轉人工 ×