Website development now can not bypass Wechat login (after all, Wechat has become a national tool).Although the documentation is detailed, it is easy for inexperienced developers to tread on holes.
Therefore, it is convenient to record the interactive logic of WeChat Web page authentication and review it later:
- Load the WeChat web page sdk
- Draw landing codes: new tab page drawing / iframe drawing of this page
- User Scavenger Logon, Front End Jump Callback URL
- Callback web addresses are further logically processed, and if in-page iframe draws a QR code, the top page needs to be notified
(vii) Read more series of articles / Read the original text
WeChat Web SDK Loading
In multi-person team collaboration, code that loads resources requires extra care.This can cause duplicate loading of resources because multiple developers may call it under the same business logic.
There are two ways to handle this. The first is to expose redundant interfaces externally, specifically to check whether duplicate loading occurs.However, considering that the caller needs to explicitly call the check() method to check each time before loading, there will inevitably be omissions.
So take the second approach, the cache mode in design mode, with the following code:
// Memo mode: prevent duplicate loading export const loadWeChatJs = (() => { let exists = false; // Docking const src = '//Res.wx.qq.com/connect/zh_CN/htmleedit/js/wxLogin.js'; //WeChat sdk web address return () => new Promise((resolve, reject) => { // Prevent duplicate loading if(exists) return resolve(window.WxLogin); let script = document.createElement('script'); script.src = src; script.type = 'text/javascript'; script.onerror = reject; // TODO: Remove script tags when failing script.onload = () => { exists = true; resolve(window.WxLogin); }; document.body.appendChild(script); }); })();
Draw landing codes
according to WeChat Landing Development Guide , pass the parameter to window.WxLogin().
// WeChat Default Configuration const baseOption = { self_redirect: true, // true: in-page iframe jump; false: new tab open id: 'wechat-container', appid: 'wechat-appid', scope: 'snsapi_login', redirect_uri: encodeURIComponent('//1.1.1.1/'), state: '', }; export const loadQRCode = (option, intl = false, width, height) => { const _option = {...baseOption, ...option}; return new Promise((resolve, reject) => { try { window.WxLogin(_option); const ele = document.getElementById(_option['id']); const iframe = ele.querySelector('iframe'); iframe.width = width? width : '300'; iframe.height = height? height : '420'; // Handle internationalization intl && (iframe.src = iframe.src + '&lang=en'); resolve(true); } catch(error) { reject(error); } }); };
Among the business components you need to use, you can call them in the periodic function componentDidMount, with demo code below:
componentDidMount() { const wxOption = { // ... }; loadWeChatJs() .then(WxLogin => loadQRCode(wxOption)) .catch(error => console.log(`Error: ${error.message}`)); }
Callback web address communicates with iframe
This piece of logic I think is the most complex and difficult to understand in WeChat's landing interaction.As mentioned at the beginning, there are two ways to render WeChat QR codes, one is to open a new tab, the other is to insert iframe into a container with a specified id.
Undoubtedly, the second way of interacting is more user-friendly, because code processing is more challenging when it comes to page communication at different levels.
For illustration purposes, first look at the simulated data configuration:
// The redirect address is taken by the back end, the back end is redirected to this address, and the front end visits this page // Parameters in the redirect address are reserved for use by front-end personnel; the back-end adds more fields to meet business needs and returns to the front-end together const querystr = '?' + stringify({ redirect: encodeURIComponent(`${window.location.origin}/account/redirect?` + stringify({ to: encodeURIComponent(window.location.origin), origin: encodeURIComponent(window.location.origin), state: 'login' })), type: 'login' }); const wxOption = { id: 'wechat-container', self_redirect: true, redirect_uri: encodeURIComponent(`//1.1.1/api/socials/weixin/authorizations${querystr}`//WeChat callback request address };
Front and Back End, WeChat Server, Client Interaction Logic
Following the configuration above, I describe the logic of front-end, client, WeChat server and back-end interaction:
- The front-end loads a two-dimensional code based on wxOption, and all information is placed in the two-dimensional code.Also listens for messages from the WeChat server.
- User mobile scanner informs Wechat server to confirm landing.
- The WeChat server receives the user's scanner request and forwards it to the front end.
-
The front end receives a message from the WeChat server and jumps to this url address based on the redirect_uri parameter of wxOption.Be careful:
- This interface address is backend and requested by GET
- Front end carries parameters by splicing params
- The address is spliced into a temporary token from the WeChat server, which is given to the back end in exchange for the user's public key
- The backend receives a request from/api/socials/weixin/authorizations${querystr} to decode the information in the querystr.Then request the user's public key from the WeChat service.Root out the front-end conventions (the redirect field is used in demo), redirect to the redirect field specified in the front-end, and stitch together more information such as user public keys.
- Front End knows redirection and jumps to the redirected route (account/redirect is used in demo)
- After the corresponding routing process, data such as user keys from the end-end can be processed.
- At this point, the four-end interactive logic of WeChat authentication is completed
Cross Iframe Communication
The previous process is complete, and now the two-dimensional code area of the iframe on the page has been replaced with the contents of / account/redirect?...
In order to communicate, you need to listen for the message event during the cycle of the page and uninstall it when the component is uninstalled:
componentDidMount() { // ... ... window.addEventListener('message', this.msgReceive, false); } componentWillUnmount() { window.removeEventListener('message', this.msgReceive); } msgReceive(event) { // Is monitoring a secure iframe? if(!event.isTrusted) { return; } console.log(event.data); // Get data from iframe for further logical processing }
In the component corresponding to the route, /account/redirect?..., we need to parse the params parameter in the route and pass the result to the previous page after checking according to business logic:
componentDidMount() { // step1: Get the params parameter in the url const querys = getQueryVariable(this.props.location.search); // step2: Check that the data in queries meets the requirements... // step3: Deliver messages to top-level pages return window.parent && window.parent.postMessage('data', '*'); }
At this point, the process of WeChat web page authentication is completed.
More: For more details on iframe communication, check the MDN documentation
More Series Articles
Collection/Subscription on GitHub
Front End Knowledge System
- JavaScript basics comb (top)
- JavaScript basics comb (next)
- Sorting up the ES6 Difficulties
- Talk about the execution order of promise/async/await and the BUG of V8 engine
- Source implementation of common examinations in front-end interviews
- Flex Getting Started and Fighting
- ......
Design Mode Manual
- Singleton mode
- Policy Mode
- proxy pattern
- Iterator mode
- Subscription-Publishing Mode
- Bridge mode
- Memento
- Template mode
- Abstract Factory Mode
- ......
Webpack4 Progressive Tutorial
- webpack4 series of tutorials (2): Compiling ES6
- webpack4 Series Tutorial (3): Multi-page Solution - Extracting Common Code
- webpack4 series tutorials (4): Single page solution--code splitting and lazy loading
- webpack4 Series Tutorial (5): Processing CSS
- webpack4 Series Tutorials (8): JS Tree Shaking
- webpack4 series of tutorials (12): Working with third-party JavaScript Libraries
- Webpack 4 Series Tutorials (15): Development Modes and webpack-dev-server
- ......