ホームページ  >  記事  >  WeChat アプレット  >  WeChat アプレット シミュレーション Cookie の実装

WeChat アプレット シミュレーション Cookie の実装

不言
不言オリジナル
2018-06-22 16:52:233666ブラウズ

この記事は主に WeChat アプレット シミュレーション Cookie の実装を紹介します。内容は非常に優れているので、参考として共有します。

開発の背景

既存のシステムにはすでに完全なインターフェースがあり、ユーザーのステータスと検証はすべてCookieに基づいています。

一部の企業ではミニ プログラム バージョンを使用する必要があります。ご存知のとおり、WeChat ミニ プログラムは Cookie をサポートしていません。オンラインで立ち上げる必要があるビジネスの場合、既存のインターフェイスのセットに基づいて行うのが最善の方法であり、あまり変更がなく、最も高速です。

Cookieのシミュレーション

ブラウザの開発ツールとネットワークバーを通じてリクエストを表示します。ブラウザ内のCookieは、Cookieをキー名として使用して、各httpのリクエストヘッダーに含まれます。

次に、WeChat の公式リクエスト メソッド wx.request でヘッダーを設定し、Cookie を追加します。これはシミュレートできるはずです。

サーバーから返される Cookie を取得する方法という問題が再び生じます。

ログイン インターフェイスを通じて (ログイン時に、サーバーはセッションとして Cookie を埋め込みます)、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,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__';

/**
 * 格式化用户需要的 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=/;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

normalizeUserCookie は主に xx=xxx のようなデータをフィルタリングし、次に path=/; のような無意味なデータを除外します。 。 <p></p>インターフェースにログインするときに、Cookie を保存して次のリクエストに持ち込んでください。そうすれば、おそらくシミュレートできるはずです。 <p></p> <p class="jb51code"></p>Egg.js を使用すると<p></p> <p></p> <p>Egg の組み込み <code> Egg-security プラグインは、デフォルトですべての「非セキュリティ」メソッド (POST、PUT、そして削除します。

Egg.js CSRF は設定でオフにすることができますが、CSRF を使用しなければならない場合はどうすればよいでしょうか?

まず、csrfToken がどのようにして来たのかを理解する必要があります。
多くの検証を行った結果、http リクエストが合意された場所に csrfToken 値を含まない場合、このリクエストは返される Cookie に新しい csrfToken を含むことになり、このリクエストがすでに値を含んでいる場合は生成されないことがわかりました。 csrfToken に変換します。合意された場所にある csrfToken が Cookie 内の csrfToken と一致する場合、検証は合格します。

ユーザーが必要とする上記の 形式の Cookie 操作を続行し、最初に csrfToken を脇に置き、ユーザーのステータスのみを処理します。 各リクエストの後、Cookie に存在する可能性のある csrfToken を個別に取得しようとします。値がある場合は、それをキャッシュします。値がない場合は、スキップして古い値を使用します。

Ajaxをカプセル化します

🎜🎜🎜このアプレットはwepyに基づいているため、Egg.jsバージョンに基づいて最適化されたwepy.request;🎜🎜が使用されます。 🎜🎜実際の開発とは若干異なる場合がありますので、適宜修正してください。 🎜🎜🎜
import wepy from &#39;wepy&#39;;

export const HTTP_HOST = &#39;http://127.0.0.1:3000&#39;;

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

// cookie 的本地存储位置
const COOKIE_KEY = &#39;__cookie_key__&#39;;
// csrfToken 的本地存储位置
const CSRF_TOKEN_KEY = &#39;__csrf_token__&#39;;

/**
 * 清除用户Cookie
 */
export const cleanUserCookie = () => {
  wx.setStorageSync(COOKIE_KEY, &#39;&#39;);
}

/**
 * 格式化用户需要的 cookie
 * @param {String} cookies
 */
export const normalizeUserCookie = (cookies = &#39;&#39;) => {
  let __cookies = [];
  (cookies.match(/([\w\-.]*)=([^\s=]+);/g) || []).forEach((str) => {
    if (str !== &#39;path=/;&#39; && str.indexOf(&#39;csrfToken=&#39;) !== 0) {
      __cookies.push(str);
    }
  });
  wx.setStorageSync(COOKIE_KEY, __cookies);
};

/**
 * 格式化 token
 */
const normalizeCsrfToken = () => {
  let __value = wx.getStorageSync(CSRF_TOKEN_KEY) || &#39;&#39;;
  let __inputs = __value.match(/csrfToken=[\S]*/) || [];
  let __key = __inputs[0]; // csrfToken=1212132323;
  if (!!!__key) {
    return &#39;&#39;;
  }
  // 脱水
  return __key.replace(/;$/, &#39;&#39;).replace(/^csrfToken=/, &#39;&#39;);
};

/**
 * 保存 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(
      {
        &#39;x-csrf-token&#39;: csrf,
        Cookie: Cookies.join(&#39; &#39;)
      },
      opt.header || {}
    );
    opt.success = (data) => {
      seveCsrfTokenCookie(data.header[&#39;set-cookie&#39;]);
      // 统一操作
      if (data.statusCode == 200) {
        if (url === &#39;/login&#39;) {
          normalizeUserCookie(data.header[&#39;set-cookie&#39;]);
        }
        resolve(data.data);
      } else {
        reject(&#39;未知错误,请重试一次&#39;);
      }
    };
    opt.fail = (err) => {
      reject(err);
    };
    opt.url = `${HTTP_HOST_API}${opt.url}`;
    wepy.request(opt);
  });
};
🎜🎜🎜 以上がこの記事の全内容です。その他の関連コンテンツについては、PHP 中国語 Web サイトをご覧ください。 🎜🎜関連するおすすめ: 🎜🎜🎜WeChat ミニ プログラム Page()関数の紹介🎜🎜🎜🎜🎜WeChatミニプログラムでのwx:forとwx:for-itemの使い方🎜🎜🎜🎜🎜🎜🎜

以上がWeChat アプレット シミュレーション Cookie の実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。