之前一直做PC端比较多,最近在做公司的微信企业号,涉及到一个问题,我们这个公众号是为特定的企业开放的,用于园区资产平台管理,所以涉及到一个用户登录认证的问题。
一、描述。
在微信的内部页面运行:当用户未关注公众号(或企业号),则自动引导到关注画面,关注后进入公众号,公众号中有“主页”,用户点击进入我们的平台,可以实现提交工单服务需求,查看园区信息等。但是在进入我们平台时需要做一个登录认证。
具体:如果用户尚未登录(未获取到其身份信息)时,则跳至特定页面获取凭证。已经登录则继续判断是否与我们平台进行了绑定,没有绑定则跳至绑定页面填写信息进行绑定,成功后方可进入平台。
二、实现。
由于平台开发文档发生了更新,所以流程变化如下:
最终流程:在平台内的任一页面,判断该 Url 中是否有 accessKey 参数存在,无则跳至指定 url 获取 accessKey,获取后自动跳至主页;有则跳转至主页,按照我们设置的流程进入我们的平台。在进入平台主页时判断用户是否与平台绑定,已绑定则存 accessKey ,没绑定则跳至绑定页面进行绑定。
【 即上图 3 中去掉了主页判断。 】
所以,在公共js文件中:
1、判断有无凭证(accessKey)。
// 内部认证参数 var APPID = ‘‘; var REDIRECT_URI = encodeURIComponent("redirect_uri"); var SCOPE = ‘snsapi_userinfo‘; // 静默授权 var STATE = ‘home‘; // 认证后跳转的目标 var url_accessKey = getUrlParam(‘accesskey‘); /*判断有无凭证*/ if(url_accessKey){ legal(); }else{ if (window.localStorage.getItem(‘accesskey‘)) { accessKey = window.localStorage.getItem(‘accesskey‘); my_userId = window.localStorage.getItem(‘userId‘); my_userName = window.localStorage.getItem(‘userName‘); var saveTime = localStorage.getItem(‘saveTime‘); var nowdate = (new Date()).getTime(); var a = nowdate - saveTime; a= (a/1000/60/60/24); if (a > 2) { illegal(); // 无凭证或非法,跳到特定页面获取凭据 } }else{ //alert(window.localStorage.getItem(‘accesskey‘)); //alert(‘url+local都无,无凭证,去获取‘); illegal(); // 无凭证或非法,跳到特定页面获取凭据 } }
【 上述内部认证参数 APPID、REDIRECT_URI、SCOPE、STATE 在平台开发文档中有,这里的 APPID 和 REDIRECT_URI 就不写出来了。 】
但是,值得注意的一个地方是,REDIRECT_URI 需要编码,不能直接写文档中的 http://.....
2、有无凭证情况下执行对应函数。
function illegal(){ var new_href = (‘https://open.weixin.qq.com/connect/oauth2/authorize?appid=‘+APPID+‘&redirect_uri=‘+REDIRECT_URI+ ‘&response_type=code&scope=‘+SCOPE+‘&state=‘+STATE+‘#wechat_redirect‘).toLowerCase(); window.location.href = new_href; } // 存accessKey function legal(){ // 判断用户与平台是否绑定(accessKey和userId都有) var url_accessKey = getUrlParam(‘accesskey‘); var url_userId = getUrlParam(‘userid‘); var url_userName = getUrlParam(‘userName‘); localStorage.setItem(‘accesskey‘, url_accessKey); // localStorage.setItem(‘userName‘, url_userName); // localStorage.setItem(‘userId‘, url_userId); // localStorage.setItem(‘saveTime‘, (new Date()).getTime());// 保存变量时的时间点,当前时间戳) my_userId = url_userId; my_userName = url_userName; accessKey = url_accessKey; }
3、获取 url 中的参数,getUrlParam():
//获取url中的参数 function getUrlParam(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象 var r = window.location.search.substr(1).match(reg); //匹配目标参数 // if (r != null) return unescape(r[2]); return null; //返回参数值 (解析中文参数时候出现乱码) if (r != null) return decodeURI(r[2]); return null; //返回参数值 }
三、调试。
在将代码上传到服务器上之后,需要进行很重要的一步,就是调试,我们在公众号中的操作都属于正常使用,那如果用户直接访问的不是平台主页而是平台的别的页面呢,这个时候就需要使用调试工具,我用的是微信web开发者工具,用起来还可以,就是感觉每次都要清除缓存有点麻烦,不过也还好(∩_∩)
1、在 WebStorm 中运行除主页的任一页面(服务详情页面),在浏览器中会出现提示:
2、能出现提示,至少说明微信内部认证做好了,复制链接在微信web开发者工具中打开:
由于我之前已经登录了,localStorage 中已经存在 accessKey ,所以正在自动登录。
3、但是我还没有绑定信息,所以会跳至信息绑定页面:
提交信息之后,绑定成功。
【 这里有个信息绑定是因为我们的公众号的使用人群是工程服务团队的,如果使用者不在工程服务团队中,是收不到验证码,也看不到任何信息的。即文章开始说的 为特定的企业开放。】
4、再次在微信web开发者工具中打开刚刚复制的链接,这次是 之前登录过且已绑定信息 的状态:
四、手机获取验证码。
获取验证码就是使用 ajax 调用后台接口就好了,关键是我遇到一个很奇怪的问题,点击获取验证码按钮之后,手机能正常收到短信,但是,程序会跳到 ajax 的 error 函数中,因为我在 error 中写了 alert(‘error:‘+ e); 就很奇怪,别的参数都没写错,短信也能正常收到,为什么会到 error 里面去我也很无奈。同事说有跨域问题,可是我试过解决跨域问题,还是不行的,本来还想根据获取验证码成功后的返回参数来友好的提示用户的,因为这个问题,也没做了,好无奈,哈哈。如果有谁遇到同样的奇葩问题,可以教下我。
五、扩展 。
在写获取 url 中的参数的函数时候,想到了如果要在 url 后面加参数呢,于是。。。
// 在url后面加参数 function UrlUpdateParams(url, name, value){ var r = url; if (r != null && r != ‘undefined‘ && r != "") { value = encodeURIComponent(value); var reg = new RegExp("(^|)" + name + "=([^&]*)(|$)"); var tmp = name + "=" + value; if (url.match(reg) != null) { r = url.replace(eval(reg), tmp); } else { if (url.match("[\?]")) { r = url + "&" + tmp; } else { r = url + "?" + tmp; } } } return r; }