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

How to install mysql in docker

I recently deployed Django and didn't want to...

Vue song progress bar sample code

Note that this is not a project created by vue-cl...

Detailed explanation of the role of static variables in MySQL

Detailed explanation of the role of static variab...

Summary of some thoughts on binlog optimization in MYSQL

question Question 1: How to solve the performance...

How to use the Linux md5sum command

01. Command Overview md5sum - Calculate and verif...

Vue implements multiple ideas for theme switching

Table of contents Dynamically change themes The f...

Introduction to the properties of B-Tree

B-tree is a common data structure. Along with him...

Practical record of solving MySQL deep paging problem

Table of contents Preface Why does limit deep pag...

Detailed steps to install mysql in Win

This article shares the detailed steps of install...

Detailed steps to build an independent mail server on Centos7.9

Table of contents Preface 1. Configure intranet D...

Implementation of Docker deployment of Django+Mysql+Redis+Gunicorn+Nginx

I. Introduction Docker technology is very popular...

JavaScript implements Tab bar switching effects

Here is a case that front-end developers must kno...

In-depth explanation of Set and WeakSet collections in ES6

Table of contents Set is a special collection who...