最近做一个投票功能,为了防止用户恶意刷票,必须鉴别用户身份,对每个人投票次数限制。但投票是开放的,任何人都可以投,并非仅平台注册用户,因此只能使用用户最广泛的微信来识别用户,通过获取微信openid来判定用户是否已经投过票。
在vue中,需要添加一个静态html(weixinOAuth.html)来进行跳转和回跳处理。
机制: 在需要获取微信openid的页面跳转至weixinOAuth.html,weixinOAuth.html跳转微信官方鉴权页面获取code,微信鉴权页面再返回weixinOAuth.html带上code参数, weixinOAuth.html再拿code调用后端集成的微信api获取access_token及openid,将参数作为url query参数跳转至业务页面,业务页面再从url中获取参数。
跳转处理html页面:static_pages/weixin/weixinOAuth.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script type="application/javascript"> /** * 此页面实现静默获取微信openId功能,主要用于一些需要使用微信账号作为身份识别的地方 * 页面需要在微信浏览器环境下使用 * * 机制: * 在需要获取微信openid的页面跳转至本页面,本页面跳转微信官方鉴权页面获取code,微信鉴权页面再返回本页面带上code参数, * 本页面再拿code调用后端集成的微信api获取access_token及openid,将参数作为url query参数跳转至业务页面,业务页面再从url中获取openid等参数 * * 用法示例:在其他vue created() 方法里使用。 * created() { * // 微信浏览器环境 * if (navigator.userAgent.toLowerCase().includes('micromessenger')) { * // this.isWeixinBrowser = true * if (!localStorage.weixinOpenid) { * // 设置微信鉴权后跳转的页面地址, weixinOAuth.html完成鉴权后会自动跳转 * localStorage.wexinOAuthRedirect = location.href * // 跳转到鉴权页面,鉴权页面在获取到openid后会写入到localStorage * location.href = '/weixinOAuth.html' * } else { * alert('有openid:' + localStorage.weixinOpenid) * } * } else { * // this.isWeixinBrowser = false * } * }, * @param key * @returns {null|*} */ function getUrlParam(key) { if (!location.href.includes('?')) { return null } // 通过 ? 分割获取后面的参数字符串 let urlStr = location.href.split('?')[1]; // 创建空对象存储参数 let obj = {}; // 再通过 & 将每一个参数单独分割出来 let paramsArr = urlStr.split('&'); for(let i = 0,len = paramsArr.length;i < len;i++){ // 再通过 = 将每一个参数分割为 key:value 的形式 let arr = paramsArr[i].split('='); obj[arr[0]] = arr[1]; } return obj[key]; } async function start() { const code = getUrlParam('code'); const state = getUrlParam('state'); if (!code) { // alert('跳转至微信平台去鉴权') const appid = 'wxd83?????????a44'; const redirect_uri = encodeURIComponent(location.href); // 微信鉴权回调跳转到本页 const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=snsapi_base&state=abc#wechat_redirect`; console.info('去微信平台获取code,url:', url) // alert('跳转链接:' + url) window.location.href = url; } else { console.info(`接收到微信回调,code:${code}`) // alert(`接收到微信回调,code:${code},请求后端获取openId`) // localStorage.weixinOAuthCode = code; // localStorage.weixinOAuthState = state; // 查询用户openId const response = await fetch('https://你的后端.com/cus/WeixinController/weixinOAuth?code=' + code); const result = await response.json(); // alert('查询用户OpenId结果:' + JSON.stringify(result)) if (!result || !result.success) { // alert('获取用户信息失败') return } /* 正常情况将返回: { "success": "success", "data": { "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE", "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" } } */ const data = result.data console.info('查询用户openId data', data) // alert(`查询用户openId: ${data.openid}`) if (data.access_token && data.openid) { // localStorage.weixinOpenid = data.openid // localStorage.weixinAccessToken = data.access_token // alert('localStorage.weixinOpenid: ' + localStorage.weixinOpenid) // alert('localStorage.weixinAccessToken: ' + localStorage.weixinAccessToken) // 微信回调传回来的参数 if (localStorage.wexinOAuthRedirect) { // alert(`跳转至业务页面:${localStorage.wexinOAuthRedirect}`) // 将openid拼接到要回调的页面的url参数中(这里为什么不放进localstorage里?为了提升伪造难度) let newUrl = localStorage.wexinOAuthRedirect if (localStorage.wexinOAuthRedirect.includes('?') && localStorage.wexinOAuthRedirect.includes('&')) { newUrl += '&' } else if (localStorage.wexinOAuthRedirect.includes('?')) { newUrl += '&' } else { newUrl += '?' } newUrl += 'weixinOpenid=' + data.openid + '&weixinAccessToken=' + data.access_token location.href = newUrl } else { // alert('无可跳转业务页面'); } } else { // alert('查询用户openId失败'); } } } </script> </head> <body onl oad="start()" style="display: flex;justify-content: center;align-items: center;font-size: 4vw;"> 请稍候... </body> </html>
webpack.base.conf.js添加文件复制配置
plugins: [ new webpack.optimize.CommonsChunkPlugin('common.js'), new CopyWebpackPlugin([ { from: 'aaa/bbb/xxx', to: 'xxx' }, { from: 'static_pages/weixin', to: '' // 复制到根目录 } ]) ]
业务页面vue
created() { // 使用微信用户openid作为身份识别,防止刷票 if (navigator.userAgent.toLowerCase().includes('micromessenger')) { this.isWeixinBrowser = true // 获取url参数中的openid,如果没有则跳转去鉴权 const weixinOpenid = this.getUrlParam('weixinOpenid') const weixinAccessToken = this.getUrlParam('weixinAccessToken') if (!weixinOpenid) { // alert('无openid,跳转weixinOAuth.html') localStorage.wexinOAuthRedirect = location.href location.href = '/weixinOAuth.html' } else { this.weixinOpenId = weixinOpenid this.weixinAccessToken = weixinAccessToken // alert('有openid:' + localStorage.weixinOpenid) } } else { this.isWeixinBrowser = false } },
标签:openid,vue,微信,code,localStorage,跳转,中微信,页面 From: https://www.cnblogs.com/jsper/p/17502409.html