Small alternative program development Tips - User Authorization articles

 

This article help solve some of the functional interface Reauthorization + unified management (for wx contains extended objects), such as access to geographic information, address harvesting, recording, licensing issues

Small alternative program development Tips - User Authorization articles

getUserInfo more specific, not included in the scope of this, mainly for functional api requires authorization, for example: wx.startRecord , wx.saveImageToPhotosAlbumwx.getLocation

Original Address: https://www.yuque.com/jinxuanzheng/gvhmm5/arexcn

Warehouse Address: https://github.com/jinxuanzheng01/weapp-auth-demo

background

If you want to call the program a small part of the user interface needs to be authorized, such as access to geographic information, address harvesting, recording, etc., but not particularly friendly applet requires authorization for these interfaces, most notably two points:

  • If the user has refused authorization, it will not appear pop , but directly into the interface to fail callback ,
  • There is no uniform error message prompts , such as error codes

Generally the case, should be authorized to activate each time pop prompt, whether to authorize, such as:

While only the first authorization within the applet will take the initiative to activate pop (micro letter provided), other cases will go directly to fail callback, micro-letters also document the end of the sentence add a sentence please developer compatible user denying authorization scene in this without making compatible if a user wants to use the recording function, first click to refuse authorization, then in any case does not turn on after recording ** permission again, obviously not in line with our expectations.

So we need a secondary authorization solutions

Common treatment methods

The official demo

The following code is the authorization code provided by the official micro-channel can be seen also not compatible refused authorization scene query whether to authorize (ie, can not be recalled from the reauthorization)

// 可以通过 wx.getSetting 先查询一下用户是否授权了 "scope.record" 这个 scope
wx.getSetting({
  success(res) {
    if (!res.authSetting['scope.record']) {
      wx.authorize({
        scope: 'scope.record', success () { // 用户已经同意小程序使用录音功能,后续调用 wx.startRecord 接口不会弹窗询问 wx.startRecord() } }) } } }) 

General approach

So under normal circumstances, how do we do it? Geographic location information to authorize an example:

wx.getLocation({
   success(res) { 
      console.log('success', res);
   },
   fail(err) {
      // 检查是否是因为未授权引起的错误
      wx.getSetting({
         success (res) {               
            // 当未授权时直接调用modal窗进行提示
            !res.authSetting['scope.userLocation'] && wx.showModal({ content: '您暂未开启权限,是否开启', confirmColor: '#72bd4a', success: res => { // 用户确认授权后,进入设置列表 if (res.confirm) { wx.openSetting({ success(res){ // 查看设置结果 console.log(!!res.authSetting['scope.userLocation'] ? '设置成功' : '设置失败'); }, }); } } }); } }); } }); 

The above code, some students might fail directly in the callback in use wx.getSetting some questions , mainly because here

  • Micro-channel error message is returned without a unified code
  • errMsg they behave differently on different platforms
  • Buried data from conclusion, calling these interfaces api error rate is concentrated in the unauthorized state

Here for the convenience of directly calling the authorization check, you can also package a little bit, to facilitate the expansion and reuse, becomes:

  bindGetLocation(e) {
        let that = this;
        wx.getLocation({
            success(res) {
                console.log('success', res);
            },
            fail(err) {
                that.__authorization('scope.userLocation'); } }); }, bindGetAddress(e) { let that = this; wx.chooseAddress({ success(res) { console.log('success', res); }, fail(err) { that.__authorization('scope.address'); } }); }, __authorization(scope) { /** 为了节省行数,不细写了,可以参考上面的fail回调,大致替换了下变量res.authSetting[scope] **/ } 

It looks like no problem, fail in just introduced a line of code,

Here, if only for a few pages, then I think it has been good enough, after all ** 'unless absolutely necessary, do not by entity' , but for a small punch could this small program for pages related to the need to call the scene above normal * * I do not want to always artificial to call these methods, after all, people always make mistakes

Carding target

As already mentioned in the background and a common approach, then sort out what our goals, we in the end in order to solve the problem ? Listed under roughly the following three points:

  • Compatible user refused to authorize a scene that provides Reauthorization
  • Solve the multi-scene, multi-page call no standardized questions
  • At the bottom solving, business layer does not need to be concerned about the problem of secondary authorization

Extended wx [funcName] Method

In order to save costs and reduce the cognitive error probability , I hope he is the default api carrying function, that is due to an error when unauthorized auto-play is turned on authorization of pop

To achieve this, we may need to native api to wx is carried layer wraps (page can be seen on the packaging: how to build native-based micro-channel application-level applet underlying architecture )

Add your own methods to wx.getLocation

One thing to note here is the direct use common decorative pattern will emerge error , because wx this object while setting the property is not set method , where the need to handle it alone

// 直接装饰,会报错 Cannot set property getLocation of #<Object> which has only a getter 
let $getLocation = wx.getLocation;
wx.getLocation = function (obj) { $getLocation(obj); }; // 需要做一些小处理 wx = {...wx}; // 对wx对象重新赋值 let $getLocation = wx.getLocation; wx.getLocation = function (obj) { console.log('调用了wx.getLocation'); $getLocation(obj); }; // 再次调用时会在控制台打印出 '调用了wx.getLocation' 字样 wx.getLocation() 

Hijack fail method

The first step we have control of the wx.getLocation this api, the next step is to fail method of hijacking, because we need to add our own authorization logic fail in

// 方法劫持
wx.getLocation = function (obj) {
    let originFail = obj.fail; obj.fail = async function (errMsg) { // 0 => 已授权 1 => 拒绝授权 2 => 授权成功 let authState = await authorization('scope.userLocation'); // 已授权报错说明并不是权限问题引起,所以继续抛出错误 // 拒绝授权,走已有逻辑,继续排除错误 authState !== 2 && originFail(errMsg); }; $getLocation(obj); }; // 定义检查授权方法 function authorization(scope) { return new Promise((resolve, reject) => { wx.getSetting({ success (res) { !res.authSetting[scope] ? wx.showModal({ content: '您暂未开启权限,是否开启', confirmColor: '#72bd4a', success: res => { if (res.confirm) { wx.openSetting({ success(res){ !!res.authSetting[scope] ? resolve(2) : resolve(1) }, }); }else { resolve(1); } } }) : resolve(0); } }) }); } // 业务代码中的调用 bindGetLocation(e) { let that = this; wx.getLocation({ type: 'wgs84', success(res) { console.log('success', res); }, fail(err) { console.warn('fail', err); } }); } 

You can see now realize the function has reached the beginning of our expectations , that as a result of being given authorization to carry wx.getLocation default function, we no longer need to deal with any authorized business logic code again

This also means that wx.getLocation api whether any pages, components, how the frequency of appearance, ** we do not need to care about its authorization logic (** effect originally wanted to stick gif graph, chart point later found to have a large, concrete results go git repository run about demo of it)

Let us optimize wave

The above is roughly the whole idea of ​​a principle, but applied to practical projects also need to consider the overall scalability and maintenance costs, then let us come back to optimize wave

Code package structure:
essentially as long as the app.js this startup file, the original file reference ./x-wxx/index wx objects can be covered

Simple code logic **: **

// 大致流程:

//app.js
wx = require('./x-wxx/index');						// 入口处引入文件 // x-wxx/index const apiExtend = require('./lib/api-extend'); module.exports = (function (wxx) { // 对原有方法进行扩展 wxx = {...wxx}; for (let key in wxx) { !!apiExtend[key] && (()=> { // 缓存原有函数 let originFunc = wxx[key]; // 装饰扩展的函数 wxx[key] = (...args) => apiExtend[key](...args, originFunc); })(); } return wxx; })(wx); // lib/api-extend const Func = require('./Func'); (function (exports) { // 需要扩展的api(类似于config) // 获取权限 exports.authorize = function (opts, done) { // 当调用为"确认授权方法时"直接执行,避免死循环 if (opts.$callee === 'isCheckAuthApiSetting') { console.log('optsopts', opts); done(opts); return; } Func.isCheckAuthApiSetting(opts.scope, () => done(opts)); }; // 选择地址 exports.chooseAddress = function (opts, done) { Func.isCheckAuthApiSetting('scope.address', () => done(opts)); }; // 获取位置信息 exports.getLocation = function (opts, done) { Func.isCheckAuthApiSetting('scope.userLocation', () => done(opts)); }; // 保存到相册 exports.saveImageToPhotosAlbum = function (opts, done) { Func.isCheckAuthApiSetting('scope.writePhotosAlbum', () => done(opts)); } // ...more })(module.exports); 

More games are played

We can see that regardless of any subsequent expansion of micro-channel api, only need to configure them in lib / API-extend.js , here is not limited authorization, you can also do some logging, mass participation of adjustment , such as:

 // 读取本地缓存(同步)
exports.getStorageSync = (key, done) => {
        let storage = null; try { storage = done(key); } catch (e) { wx.$logger.error('getStorageSync', {msg: e.type}); } return storage; }; 

This is not very easy to do, as Func.isCheckAuthApiSetting specific implementation of this method, the number of articles in order to save your own lines to the warehouse git view it

About Audio authorization

Recording slightly special authorization to wx.getRecorderManager example, it can not be directly transferred from the recording authorization , and therefore it can not be directly above this method, but we can Quxianjiuguo, achieve a similar effect, we remember for wx.authorize What packaging, essentially we can use it directly for authorization, such as it is used in the method we have packaged start recording manager verifies

wx.authorize({
   scope: 'scope.record'
});

In fact, to facilitate unified management, Func.isCheckAuthApiSetting methods are actually realized authorized to use wx.authorize

exports.isCheckAuthApiSetting = async function(type, cb) {

        // 简单的类型校验 if(!type && typeof type !== 'string') return; // 声明 let err, result; // 获取本地配置项 [err, result] = await to(getSetting()); // 这里可以做一层缓存,检查缓存的状态,如果已授权可以不必再次走下面的流程,直接return出去即可 if (err) { return cb('fail'); } // 当授权成功时,直接执行 if (result.authSetting[type]) { return cb('success'); } // 调用获取权限 [err, result] = await to(authorize({scope: type, $callee: 'isCheckAuthApiSetting'})); if (!err) { return cb('success'); } } 

About user authorization

User Authorization very special, because micro-channel will wx.getUserInfo a version upgrade, there is no way to directly evokes, see "announcement" , it is necessary to deal with alone, there will be split on a separate article to write some interesting gameplay

to sum up

Finally, a little summarize, the above solution, we have solved the very beginning while the target , but also provides a unified decorative Interface (lib / api-extend file) for the methods of wx this object, easy to follow other acts of operations such as buried point logging, calibration parameters

Or so a word of it, applets and web development regardless of how many different, are essentially developed in the js environment, community environment applet want more active, bringing more interesting things

Original link address: https: //developers.weixin.qq.com/community/develop/article/doc/0000c42fea0668ff36b80d20451813

Guess you like

Origin www.cnblogs.com/aslxwjh/p/12151005.html