当前位置: 首页 > 后端技术 > PHP

微信小程序非跳转组件授权登录

时间:2023-03-29 15:52:15 PHP

先附上官方文档地址和授权流程官方地址:https://developers.weixin.qq...流程图:大体逻辑:授权->发送代码到服务器获取session_key->保存在小程序缓存中->调用wx.getUserInfo和session_key获取用户信息->登录成功后返回accesstoken->记录登录状态->进行登录成功监听(失败不监听)直接上传代码,都是小程序组件模型。有兴趣的可以看看官方文档Createcomponents(自定义名称)文件夹pages文件夹主要是把components文件放在同级创建authorize(自定义名称)文件夹还是一样的创建对应的authorize.js,authorize.wxml。authorize.wxss,authorize.json特别注意这里的authorize.json文件将当前页面定义为一个组件{"component":true}来完成这里的准备工作来完成authorize.js并替换成一个组件.具体可以参考小程序官方文档。这里是我定义的Component({//组件的外部属性真的很官方,如果你用过vue组件就很容易理解这一点//parent传值给child,就是这个地方toreceivetheworthproperties:{//name必须绑定父name相同//这里主要是控制自动授权弹框是否显示true=hidefalse=displayiShidden:{type:Boolean,//Definetypevalue:true,//Definedefaultvalue},//这里是否自动登录主要用来在没有授权的情况下自动弹出授权提示框//**在做的页面中使用不会自动登录但有些操作需要授权才能登录**isAuto:{type:Boolean,value:true,},},//组件内部数据,与组件模板渲染数据的属性一起使用:{cloneIner:null},//组件所在页面的生命周期声明对象dpageLifetimes:{//页面隐藏hide:function(){//关闭页面时销毁定时器if(this.data.cloneIner)clearInterval(this.data.clearInterval);},//打开页面show:function(){//打开页面销毁定时器if(this.data.cloneIner)clearInterval(this.data.clearInterval);},},//组件生命周期函数,执行attached(){},//组件方法methods:{}});note:methods中需要写以下方法Step1:未授权用户判断是否进行授权或直接获取用户信息//检测登录状态,进行自动登录setAuthStatus(){varthat=this;那.setErrorCount();wx.getSetting({success(res){//会检查是否授权,如果授权则直接调用自动登录if(!res.authSetting['scope.userInfo']){//否授权不会自动弹出登录框if(that.data.isAuto===false)return;//自动弹出授权that.setData({iShidden:false});}else{//自动登录that.setData({iShidden:true});if(app.globalData.token){//这里是授权回调that.triggerEvent('onLoadFun',app.globalData.token);that.WatchIsLogin();}else{wx.showLoading({title:'登录'});//这里是授权调用wx.getUserInfothat.getUserInfoBydecryptCode();}}}})}第二步未授权打开授权弹框//AuthorizationsetUserInfo(e){varthat=this,pdata={};pdata.userInfo=e.detail.userInfo;pdata.spid=app.globalData.spid;wx.showLoading({title:'登录'});wx.login({success:function(res){if(!res.code)returnapp.Tips({title:'Loginfailed!'+res.errMsg});//获取session_key并缓存that.getSessionKey(res.code,function(){that.getUserInfoBydecryptCode();});},fail(){wx.hideLoading();}})},//从缓存中获取session_key,如果没有则请求服务器缓存getSessionKey再次(代码,successFn,errotFn){varthat=this;wx.checkSession({success:function(res){if(wx.getStorageSync('session_key'))successFn&&successFn();elsethat.setCode(code,successFn,??errotFn);},fail:function(){that.setCode(code,successFn,??errotFn);}});},//访问服务器获取session_key并存入缓存setCode(code,successFn,??errotFn){v??arthat=this;app.basePost(app.U({c:'Login',a:'setCode'}),{code:code},function(res){wx.setStorageSync('session_key',res.data.session_key);successFn&&successFn(res);},function(res){if(errotFn)errotFn(res);elsereturnapp.Tips({title:'未能获取session_key'});});}第三步:执行getUserInfoBydecryptCode登录获取访问权限getUserInfoBydecryptCode:function(){varthat=this;varsession_key=wx.getStorageSync('session_key')//没有获取到session_key,打开授权页面//这里必须要判断缓存中的session_key是否存在,因为第一步判断//授权自动执行获取用户信息的方法if(!session_key){wx.hideLoading();if(that.data.isAuto)that.setData({iShidden:false})返回false;};wx.getUserInfo({lang:'zh_CN',success:function(res){varpdata=res;pdata.userInfo=res.userInfo;pdata.spid=app.globalData.spid;//获取启动子IDpdata.code=app.globalData.code;//获取推广者分享的二维码IDif(res.iv){pdata.iv=encodeURI(res.iv);pdata.encryptedData=res.encryptedData;pdata.session_key=session_key;//获取用户信息并生成accesstokenapp.basePost(app.U({c:'login',a:'index'}),{info:pdata},function(res){if(res.data.status==0)returnapp.Tips({title:'抱歉,您已被禁止登录!'},{tab:4,url:'/pages/login-status/login-status'});elseif(res.data.status==410){wx.removeStorage({key:'session_key'});wx.hideLoading();if(that.data.iShidden==true)that.setData({iShidden:false});返回fa是;}//取消登录提示wx.hideLoading();//关闭登录弹窗that.setData({iShidden:true,ErrorCount:0});//保存token并记录登录状态app.globalData.token=res.data.token;app.globalData.isLog=true;//执行登录完成回调that.triggerEvent('onLoadFun',app.globalData.uid);//监听登录状态that.WatchIsLogin();},function(res){wx.hideLoading();返回app.Tips({title:res.msg});});}else{wx.hideLoading();returnapp.Tips({title:'获取用户信息失败!'});}},失败:function(){wx.hideLoading();that.setData({iShidden:false});},})}第四步:监听登录状态,当服务器获取token失败时,当前页面会一直监听token是否为空,防止无限访问token设置错误的个数。监控token终止监控的目的是:token是服务器返回给当前用户的访问凭证。当凭证过期时,此时所有的网络请求都将无法访问,所以用了一个笨办法来监听token//监听登录状态WatchIsLogin:function(){this.data.cloneIner=setInterval(function(){//防止死循环,如果错误次数超过则终止监听if(this.getErrorCount())returnclearInterval(this.data.clearInterval);if(app.globalData.token=='')this.setAuthStatus();}.bind(this),800);this.setData({cloneIner:this.data.cloneIner});}/***处理错误数以防止无限循环**/setErrorCount:function(){if(!this.data.ErrorCount)this.data.ErrorCount=1;否则this.data.ErrorCount++;this.setData({ErrorCount:this.data.ErrorCount});},/***获取错误次数,是否停止监听**/getErrorCount:function(){returnthis.data.ErrorCount>=10?真假;}以上就是组件中所有需要在组件生命周期函数中调用第一步方法检测授权的方法,执行loginattached(){this.setAuthStatus();}注意:在网络请求中,必须处理token失效的操作,主要是将app.globalData.token和app.globalData.isLog设置回空和false,这里附上一些app中没有定义的常用快捷方式。下面的方法最好写在其他文件中。在app.js中写一个快捷调用方法/**postnetworkrequest*@paramstring|对象请求地址*@param对象数据POST请求数组*@paramcallablesuccessCallback成功执行方法*@paramcallableerrorCallback失败执行方法*/constbasePost=function(url,data,successCallback,errorCallback,header){if(typeofurl=='object')url=U(url);wx.request({url:url,data:data,dataType:'json',method:'POST',header:header,success:function(res){try{if(res.data.code==200){successCallback&&successCallback(res.data);}else{if(res.data.code==402)getApp().globalData.token='',getApp().globalData.isLog=false;//当返回状态为401,用户禁止访问关闭当前所有页面,跳转到用户禁止登录页面if(res.data.code==401)returnTips({title:res.data.msg},{tab:4,url:'/pages/login-status/login-status'});errorCallback&&errorCallback(res.data);}}catch(e){console.log(e);}},fail:function(res){errorCallback&&errorCallback(res);},complete:function(res){}});}/**组装URl*@paramobjectopt*/constU=function(opt,url){varm=opt.m||'routine_two',c=opt.c||'auth_api',a=opt.a||'索引',q=opt.q||'',p=opt.p||{},参数='',获取='';如果(url==未定义)url=getApp().globalData.url;params=Object.keys(p).map(function(key){returnkey+'/'+p[key];}).join('/');gets=Object.keys(q).map(function(key){returnkey+'='+q[key];}).join('&');返回url+'/'+m+'/'+c+'/'+a+(params==''?'':'/'+params)+'.html'+(gets==''?'':'?'+gets);}代码量有点多,但是可以用,望大神多多指教。本小程序后台框架由http://github.crmeb.net/u/blue提供。提供TP5+EasyWeChat技术支持。如果对微信小程序授权不熟悉,可以使用EasyWeChat。它真的很容易使用;不是吹这个EasyWeChat就是这个,我只是觉得好用,所以不要喷