微信公众号web页面开发遇到的那些坎——微信授权登陆

首先本次开发用到了vue作为本次前端开发框架,weui作为前端UI框架。设计思路无论用户进入哪个页面,都要进行身份的认证。具体的身份认证流程如下图所示。
在这里插入图片描述

需要注意的坑

  1. 坑1:在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名。请注意,这里填写的是域名(是一个字符串),而不是URL,因此请勿加 http:// 等协议头
    解决:本地测试需要用到外网穿透。我们用的花生壳将本地访问找一个类似于域名代理地址室的东西。将微信公众号js域名认证的txt文件下载放在跑起来的项目当中,进行域名认证(我尝试放在vue项目中的和index.html同层级中但是访问不到,放在static中可以即域名认证里填写的也是“域名/static”。但是不是根目录,访问路由地址“域名/#/home”就访问不到),于是在本地跑了一个Tomcat,再将txt文件放在根目录下,运行即可。
    具体操作如下:
    找到tomcat的下载地址对应的根目录下,如果webapps下没有ROOT文件夹一定要新建一个ROOT文件夹,不然还是访问不到。然后将txt文件放在ROOT下,运行tomcat.
    在这里插入图片描述
    双击bin/startup.sh运行tomcat。

在这里插入图片描述
2. 坑二网页授权的两种scope的区别说明
开始做测试的时候以为其实scope的区别不明显,但是为了防止出现错误用了scope=snsapi_userinfo,但是后来还是忍不住将代码改成了scope=snsapi_base,好奇心害死猫,手欠害死自己,当时也没在意,后来后端接口总给我返回报错。原来是我给后端用scope=snsapi_base拿到的的code后端拿不到用户基本信息。

  1. **坑三:**因为我们无法控制用户是从哪个页面进入,但是每个页面都需需要进行身份的验证,每个页面都要从localstorage拿数据吗?
    在App.vue中解决这些吧,在App.vue中定义一个globalUserInfoData,页面需要的数据都从这里去取。每个页面监听globalUserInfoData的变化来更新页面数据:
    页面之间逻辑如下图所示:
    在这里插入图片描述
//**----------------------------------APP.vue----------------------------------------**
<template>
  <div id="app">
  	<router-view :globalData="globalUserInfo" @loginAPI="loginFun" @setGlobalUserAPI="setGlobalUserInfo"/>
  </div>
</template>

<script type="text/ecmascript-6">
	import { getIsRegist, login,ajaxSubmit ,_localBaseUrl,_AppID} from "@/api/http";
	export default {
	  name: 'App',
	  data(){
	  	return{
	  		globalUserInfo:null
	  	}
	  },
	  created:function(){
	  	var localData=localStorage.getItem("userInfo");
	  	if(localData){
	  		this.globalUserInfo=JSON.parse(localData)
	  	}
	  	if(!this.globalUserInfo){
	  		var _code = this.getQueryString("code");
	        if (_code) {//获取code回调地址,通过code获取用户基本信息
	        	ajaxSubmit(
			        this.$http,
			        getIsRegist,
			        "get",
			        { code:_code },
			        resData => {
			        	if(resData.result==0){
				        	if(resData.data.isRegist){//注册过
				        		this.loginFun(resData.data.userId)
				        	}else{//未注册
				        		var globalData={}
				        		globalData.isRegist=resData.data.isRegist
				        		var baseInfo={}
				        		baseInfo.openid=resData.data.userInfo.openid
				        		baseInfo.nickname=resData.data.userInfo.nickname
				        		baseInfo.avatarUrl=resData.data.userInfo.headimgurl
				        		globalData.userInfo={...baseInfo}
				        		globalData.isPayFlag=false
				        		this.globalUserInfo={...globalData}
				        	}
			        	}else{
			        		//未注册的用户刷新页面。地址上被拼接上了code导致code过期,刷新地址栏
			        		window.location.href=_localBaseUrl
			        	}
			        }
			      );
	        }else{
	          //没有微信用户信息,没有授权-->> 需要授权,跳转授权页面
				  	var _redirectUrl=encodeURIComponent(_localBaseUrl+"login")
				  	var getUserInfoUrl="https://open.weixin.qq.com/connect/oauth2/authorize?appid="+_AppID+"&redirect_uri="+_redirectUrl+"&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect"
						window.location.href=getUserInfoUrl
	        }
	  	}
	  },
	  mounted:function(){
	  },
	  methods:{
	  	getQueryString(name) {  
	  		if(window.location.href.search(name + "=") != -1 ){
	  			var nameValue=window.location.href.split(name + "=")[1].split("&")[0];
	  			return nameValue;
	  		}else{
	  			return null;
	  		}
     },
     loginFun(_userId){
     	var globalData={}
     	globalData.userId=_userId
     	//登陆
			ajaxSubmit(
        this.$http,
        login,
        "post",
        { userId:_userId},
        resData => {
        	globalData.isRegist=true
        	globalData.isPayFlag=resData.data.isPayFlag
        	globalData.userInfo=resData.data.user
        	this.globalUserInfo={...globalData}
					//存储到localstorage
					localStorage.setItem("userInfo",JSON.stringify(this.globalUserInfo))
        }
      )
     },
     //修改全局变量给globalUserInfo
     setGlobalUserInfo(){
     	var localData=localStorage.getItem("userInfo");
	  	if(localData){
	  		this.globalUserInfo=JSON.parse(localData)
	  	}
     }
      
	  }
	}
</script>



//----------------------------------login.vue----------------------------------------



<template>
	<div class="login">
		<div class="tempImg">
		    <img src="../../../static/image/timg (2).gif" style="display: block;width: 100%;">
		    <p>正在登录...</p>
		</div>
	</div>
</template>

<script type="text/ecmascript-6">
	import {
	  ajaxSubmit,
	} from "@/api/http";
	export default {
	  name: 'login',
	  props:{
	  	globalData:{
		  		type: Object
		  	}
		},
	  created:function(){
	  },
	  watch: {
		globalData:{
			  immediate: true,    // 这句重要
		      handler (val) {
		      	if(val){
		      		var that=this
		      		setTimeout(function(){
		      			that.$router.push("/")
		      		},500)
		      	}
		          
		      }
		}
	},
	}
</script>

在子页面监听globalUserInfo的变化,这样可以及时的监听到globalUserInfo的变化,更改页面

watch: {
    globalData: {
      immediate: true,//很重要
      handler(val) {
        if (val) {
          this.isRegist = val.isRegist;
        }
      }
    }
  },

如果调用其他接口时出现session失效的问题,调用父组件的loginFun方法。进行从新登陆。

未解决的问题

  1. 导航栏,导航栏是每个页面都需要的,所以想加在app.vue中,但是在app.vue中没办法获取到this.router。怎么判断给哪个导航栏加高亮?每次都拿地址吗?地址变化太多了。可能被拼接上code,有的带参数。从地址栏直接拿太麻烦了吧?
  2. 地址栏被拼接上了code,如何解决?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值