Home >WeChat Applet >Mini Program Development >Implementation of WeChat applet simulation cookie

Implementation of WeChat applet simulation cookie

不言
不言Original
2018-06-22 16:52:233696browse

This article mainly introduces the implementation of WeChat applet simulation cookie. The content is quite good. Now I share it with you and give it as a reference.

Development background

The existing system already has a complete set of interfaces, and user status and verification are all based on cookies.

Some businesses require a mini program version. As we all know, WeChat mini programs do not support cookies. For the business to be launched online, the best way is to do it based on the existing set of interfaces. It will not change much and is also the fastest.

Simulate cookie

View the request through the browser's development tool and Network bar. The cookie in the browser will be carried in each request. In the Request Headers of http, Cookie is used as the key name.

Then, in WeChat’s official request method wx.request, we set the header and add a cookie, which should be able to be simulated.

The question comes again, how to get the cookie returned by the server.

Through the login interface (when logging in, the server will implant a cookie as a session), check the http return header.

wx.request({
  url: '/api/login',
  success: (data) => {
    if(data.statusCode === 200) {
      console.log(data);
      // data 中应该会有 Set-Cookie 或 set-cookie 的字样,嗯,那就是服务器种下的 cookie
    }
  }
})

Get the cookie and store it locally, and insert it directly the next time you request data, perfect.

Format cookie

I originally thought that cookies only need to be entered and exited to be perfectly simulated, but in actual operation I discovered that carrying The cookie sent to the server cannot be recognized.

The cookie returned by the server will carry many fields for storage, such as 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;';

Oh my god~What should I do? Filter it.

Written a simple and rough filtering solution.

// 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 is used next with Egg.js , Path=/; In some applications, it will be path=/;

normalizeUserCookie Mainly filters data like xx=xxx; Then exclude meaningless data like path=/;.

When logging in to the interface, save the cookie and bring it with the next request. Then, it should, yes, maybe, can be simulated.

Cooperate with Egg.js

Egg’s built-in egg-security plug-in defaults to all non-security 』methods, such as POST, PUT, and DELETE, all perform CSRF verification.
Egg.js Although CSRF can be turned off in the configuration, what if it must be used?

First of all, we need to understand one thing, how csrfToken came about.

After many verifications, we learned that when the http request is made, the csrfToken value is not carried at the agreed location. This request will carry a new csrfToken in the returned cookie; when this request has carried the csrfToken value, value, it will not be generated as csrfToken. When the csrfToken in the agreed location is consistent with the csrfToken in the cookie, the verification is passed.

Continue with the above Format the cookie operation required by the user, first put aside the csrfToken and handle the user status alone.

After each request, try to get the csrfToken that may exist in the cookie separately. If there is a value, cache it. If there is no value, skip and use the old value.

Encapsulate an Ajax

This applet is based on wepy, so the optimized wepy is used. request;

A version based on Egg.js.

It may be slightly different from the actual development, please modify it appropriately.

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);
  });
};

The above is the entire content of this article. I hope it will be helpful to everyone’s study. For more related content, please pay attention to the PHP Chinese website!

Related recommendations:

WeChat Mini Program Introduction to Page() function

Usage of wx:for and wx:for-item in WeChat applet

The above is the detailed content of Implementation of WeChat applet simulation cookie. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn