How to ensure that every page of WeChat Mini Program is logged in

How to ensure that every page of WeChat Mini Program is logged in

status quo

In a WeChat mini program, there is a homepage, a personal page, some list pages, detail pages, etc. Most of these pages can be shared. When a shared page is opened by another user, how can the page ensure that the user is logged in?

There are many solutions on the Internet that add an interception in the request encapsulation. If there is no token, call the login request to obtain the token before continuing.

There is nothing wrong with this solution. Just pay attention to one point. When a page is triggered by multiple requests at the same time, after all requests are intercepted, they are placed in an array. After successfully obtaining the token, iterate through the array and request one by one.

But if the requirement is a little more complicated, such as a convenience store chain app, most pages need to have a store (because it is necessary to obtain the inventory, price, etc. of the current store's products based on the store). This store is obtained by calling the backend interface based on the current location. At this time, it would be too troublesome to encapsulate it in the request.

Solution

First of all, we noticed that logging in, getting the location and our page request are asynchronous. We need to ensure that the page request is after logging in and getting the location, but if we write it for each page, the maintainability will be too poor. So we can extract a method to do this.

So the code is this:

const app = getApp()
Page({
  data: {
    logs: []
  },
  onLoad() {
    app.commonLogin(()=>{
        // Process page request })
  }
})

It seems that our problem has been solved here, but think about it again, if I want to do more, such as unified processing of onShareAppMessage for each page, but I don’t want to write it again for each page, and I want to implement a watch for each page myself, how to do it?

Further solutions

We can see that in WeChat applet, each page is a Page(), so we can add a shell to the outside of this Page, and we can have a MyPage to replace this Page. Without further ado, here is the code:

tool.js related code

/**
   * Process merge parameters */
  handlePageParamMerge(arg) {
    let numargs = arg.length; // Get the value of the passed parameter.
    let data = {}
    let page = {}
    for (let ix in arg) {
      let item = arg[ix]
      if (item.data && typeof (item.data) === 'object') {
        data = Object.assign(data, item.data)
      }
      if (item.methods && typeof (item.methods) === 'object') {
        page = Object.assign(page, item.methods)
      } else {
        page = Object.assign(page, item)
      }
    }
    page.data = data
    return page
  }

  /***
   * Merge page methods and data, compatible with {data:{}, methods:{}} or {data:{}, a:{}, b:{}}
   */
  mergePage() {
    return this.handlePageParamMerge(arguments)
  }

  /**
   * Processing component parameter merging */
  handleCompParamMerge(arg) {
    let numargs = arg.length; // Get the value of the passed parameter.
    let data = {}
    let options = {}
    let properties = {}
    let methods = {}
    let comp = {}
    for (let ix in arg) {
      let item = arg[ix]
      // Merge the initial data of the component if (item.data && typeof (item.data) === 'object') {
        data = Object.assign(data, item.data)
      }
      // Merge component property lists if (item.properties && typeof (item.properties) === 'object') {
        properties = Object.assign(properties, item.properties)
      }
      // List of methods for combined components if (item.methods && typeof (item.methods) === 'object') {
        methods = Object.assign(methods, item.methods)
      }
      if (item.options && typeof (item.options) === 'object') {
        options = Object.assign(options, item.options)
      }
      comp = Object.assign(comp, item)
    }
    comp.data = data
    comp.options = options
    comp.properties = properties
    comp.methods = methods
    return comp
  }

  /**
   * Component mixin {properties: {}, options: {}, data:{}, methods: {}}
   */
  mergeComponent() {
    return this.handleCompParamMerge(arguments)
  }

  /***
   * Synthesize a page with watch */
  newPage() {
    let options = this.handlePageParamMerge(arguments)
    let that = this
    let app = getApp()

    //Add global click login judgment if (!options.publicCheckLogin){
      options.publicCheckLogin = function (e) {
        let pages = getCurrentPages()
        let page = pages[pages.length - 1]
        let dataset = e.currentTarget.dataset
        let callback = null

        //Get callback method if (dataset.callback && typeof (page[dataset.callback]) === "function"){
          callback = page[dataset.callback]
        }
        // console.log('callback>>', callback, app.isRegister())
        //Judge whether to log in if (callback && app.isRegister()){
          callback(e)
        }
        else{
          wx.navigateTo({
            url: '/pages/login/login'
          })
        }
      }
    }

    const { onLoad } = options
    options.onLoad = function (arg) {
      options.watch && that.setWatcher(this)
      onLoad && onLoad.call(this, arg)
    }

    const { onShow } = options
    options.onShow = function (arg) {
      if (options.data.noAutoLogin || app.isRegister()) {
        onShow && onShow.call(this, arg)
        //Page embedding app.ga({})
      }
      else {
        wx.navigateTo({
          url: '/pages/login/login'
        })
      }
    }

    return Page(options)
  }

  /**
   * Synthesize components with watches, etc. */
  newComponent() {
    let options = this.handleCompParamMerge(arguments)
    let that = this
    const { ready } = options
    options.ready = function (arg) {
      options.watch && that.setWatcher(this)
      ready && ready.call(this, arg)
    }
    return Component(options)
  }

  /**
    * Set up the listener */
  setWatcher(page) {
    let data = page.data;
    let watch = page.watch;
    Object.keys(watch).forEach(v => {
      let key = v.split('.'); // Split the attributes in watch into an array with '.' let nowData = data; // Assign data to nowData
      for (let i = 0; i < key.length - 1; i++) { // Traverse the elements of the key array, except the last one!
        nowData = nowData[key[i]]; // Point nowData to its key attribute object}

      let lastKey = key[key.length - 1];
      // Assume key==='my.name', nowData===data['my']===data.my, lastKey==='name'
      let watchFun = watch[v].handler || watch[v]; // Compatible with both with and without handlers let deep = watch[v].deep; // If deep is not set, it is undefine
      this.observe(nowData, lastKey, watchFun, deep, page); //Monitor the lastKey of the nowData object
    })
  }

  /**
   * Monitor attributes and execute monitoring functions */
  observe(obj, key, watchFun, deep, page) {
    var val = obj[key];
    // Check if deep is true and val cannot be empty and typeof val==='object' (changes in values ​​in the array also require deep monitoring)
    if (deep && val != null && typeof val === 'object') {
      Object.keys(val).forEach(childKey => { // Traverse each key under the val object
        this.observe(val, childKey, watchFun, deep, page); // recursively call the monitoring function})
    }
    var that = this;
    Object.defineProperty(obj, key, {
      configurable: true,
      enumerable: true,
      set: function (value) {
        if (val === value) {
          return
        }
        // Call with the page object, change the this pointer in the function so that this.data can access the property value in data watchFun.call(page, value, val); // value is the new value, val is the old value val = value;
        if (deep) { // If it is deep monitoring, re-listen to the object in order to monitor its properties.
          that.observe(obj, key, watchFun, deep, page);
        }
      },
      get: function () {
        return val;
      }
    })
  }

Page code:

app.tool.newPage({
  data: {
    // noAutoLogin: false
  },
  onShow: function () {
    //Write the page request logic here}
}

at last

The code has been running online for a long time. The newPage package in the tool can be added according to your needs. In short, I am just providing a way of thinking here. If you have a better one, please feel free to share it.

This concludes this article on how WeChat Mini Programs ensure that every page is logged in. For more relevant content on how WeChat Mini Programs ensure page logins, please search for previous articles on 123WORDPRESS.COM or continue to browse the related articles below. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • WeChat Mini Programs - Detailed explanation of WeChat login, WeChat payment, and template messages
  • WeChat Mini Program Login Process Detailed Introduction
  • WeChat applet login registration function implementation code
  • WeChat applet implements facial recognition login sample code
  • WeChat applet calls WeChat login to obtain openid and java as a server example
  • WeChat applet automatic login PHP source code example (source code download)
  • WeChat applet authorization login and each check whether authorization instance code
  • Scan the WeChat applet code to log in to the website and implement analysis
  • Detailed explanation of WeChat applet development user authorization login

<<:  Collapsed table row element bug

>>:  Detailed explanation of Mysql function call optimization

Recommend

Mysql Chinese sorting rules description

When using MySQL, we often sort and query a field...

HTML 5.1 learning: 14 new features and application examples

Preface As we all know, HTML5 belongs to the Worl...

centos7.2 offline installation mysql5.7.18.tar.gz

Because of network isolation, MySQL cannot be ins...

Share the problem of Ubuntu 19 not being able to install docker source

According to major websites and personal habits, ...

Layim in javascript to find friends and groups

Currently, layui officials have not provided the ...

Practical experience of implementing nginx to forward requests based on URL

Preface Because this is a distributed file system...

HTML+jQuery to implement a simple login page

Table of contents Introduction Public code (backe...

Chrome monitors cookie changes and assigns values

The following code introduces Chrome's monito...

MySql 5.7.21 free installation version configuration method under win10

1. Unzip to the location where you want to instal...

How to solve the error "ERROR 1045 (28000)" when logging in to MySQL

Today, I logged into the server and prepared to m...

Detailed process of installing and configuring MySQL and Navicat prenium

Prerequisite: Mac, zsh installed, mysql downloade...

HTML hyperlink style (four different states) setting example

Copy code The code is as follows: <style type=...

How to monitor array changes in Vue

Table of contents Preface Source code Where do I ...