ホームページ > 記事 > WeChat アプレット > WeChat アプレット シミュレーション Cookie の実装
この記事は主に 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 '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); }); };🎜🎜🎜 以上がこの記事の全内容です。その他の関連コンテンツについては、PHP 中国語 Web サイトをご覧ください。 🎜🎜関連するおすすめ: 🎜🎜🎜WeChat ミニ プログラム Page()関数の紹介🎜🎜🎜🎜🎜WeChatミニプログラムでのwx:forとwx:for-itemの使い方🎜🎜🎜🎜🎜🎜🎜
以上がWeChat アプレット シミュレーション Cookie の実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。