第一步:用户同意授权,获取code
在确保微信公众账号拥有授权作用域(scope参数)的权限的前提下(服务号获得高级接口后,默认拥有scope参数中的snsapi_base和snsapi_userinfo),最初用户进入微信菜单进入打开如下页面:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限。
以前遇到scope配置都正确,一直报“该链接无法访问”,最终找出原因为OAuth2.0鉴权问题:域名需要在微信公众号中配置,在配置时需要找在服务器对应的根目录下上传一个txt文件,此时需要切记在域名配置时对应的根目录是什么,在公众号中填写正确的路径即可
snsapi_base |
获取用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面) |
snsapi_userinfo |
获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息 |
redirect_uri参数为页面跳转后的url,在菜单配置时需要用encodeURIComponent("url")编译
第二步:利用code获得openid(同一个微信公众号每一个用户只对应一个openid)
一般情况下页面链接为url?code=code形式,利用ajax把code传入后台接口并获取openid
code=window.location.href.split(/code=/)[1].split(/&/)[0]
注意:判断用户进入页面中是否成功获得openid(页面返回)
问题:在日常开发中利用openid判断用户是否注册或者是否成功获得openid并进一步获得用户的信息;
微信每次进入时的code都是随机的,并且有效期时间只有5分钟,而获得openid确实唯一的,在页面返回到主页时有时不能利用这一个code准确获取openid,不能准确判断用户是否注册或者获取用户的信息等
解决方式:
先看代码
1 $(function() { 2 var openid = sessionStorage.getItem("openid"); 3 if((openid == undefined) || (openid == null)) { 4 register(); 5 window.location.reload(); 6 } else { 7 $.ajax({ 8 type: "get", 9 url: "url?openid=" + openid, 10 async: true, 11 success: function(res) { 12 $(".my1 img").attr("src", res.img); 13 $(".my2 p").html(res.nickname); 14 } 15 }); 16 } 17 }) 18 //传code并获得用户信息 19 function register() { 20 $.ajax({ 21 type: "get", 22 url: "http://gy.guegg.com/code/getCode?code=" + window.location.href.split(/code=/)[1].split(/&/)[0], 23 async: false, 24 data:data, 25 success: function(res) { 26 sessionStorage.setItem("openid",res.openid); 27 }, 28 error: function() { 29 30 } 31 }); 32 }
代码中利用html5中sessionStorage浏览器缓存原理:
1.在用户第一次进入页面时利用code必然准确获得openid,此时把openid存入浏览器中;
2.如果用户在页面中返回主页时,先从浏览器缓存中找是否存在openid;
3.用户离开浏览器的时候openid直接删除
缺点:
用户同时在微信中观看多个微信公众号,此时openid冲突,不能利用openid?=null判断openid是哪个微信公众号
完美解决方法:
1 $(function(){ 2 var rungroup_coded=localStorage.getItem("rungroup_code"); 3 var rungroup_code=window.location.href.split(/code=/)[1].split(/&/)[0]; 4 if(rungroup_code!=rungroup_coded) { 5 register(rungroup_code);//获得openid 6 } else { 7 //操作利用openid获得所需信息 8 } 9 });
这个原理相信大家一看就懂,不做解释了!!