首页 > 其他分享 >vue中微信身份识别(openid)

vue中微信身份识别(openid)

时间:2023-06-25 11:00:54浏览次数:40  
标签:openid vue 微信 code localStorage 跳转 中微信 页面

最近做一个投票功能,为了防止用户恶意刷票,必须鉴别用户身份,对每个人投票次数限制。但投票是开放的,任何人都可以投,并非仅平台注册用户,因此只能使用用户最广泛的微信来识别用户,通过获取微信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

相关文章

  • vue项目在IE内核下打开显示白屏(亲测可用!!!)
    一.安装babel-polyfill库npminstall--savebabel-polyfill 如图二.在main.js中引入(放在最上面,一定要在第一行)import'babel-polyfill'三.在vue.config.js中加入transpileDependencies:process.env.NODE_ENV==="development"?["*"]:["*"......
  • 前端Vue仿京东加入购物车弹框立即购买弹框shopDialog自定义弹框内容
    前端Vue仿京东加入购物车弹框立即购买弹框shopDialog自定义弹框内容,下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13183效果图如下:cc-shopDialog使用方法使用注意:该插件需引用cc-radioBtnBox插件和cc-numbox插件两个插件库cc-radioBtn......
  • 前端Vue自定义地址展示地址选择地址管理组件
    前端Vue自定义地址展示地址选择地址管理组件,下载完整代码请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13181效果图如下:cc-addressBox使用方法<!--addressItem:地址条目数据@click:地址点击设置事件--><cc-addressBox:addressItem="item"@click="......
  • 基于uni-app+vue3渲染markdown格式|uniapp软键盘顶起问题解决方案
    前些时候有给大家分享一篇uni-app+vite4+uview-plus搭建跨端项目。今天主要分享下在uniapp中渲染markdown语法及uniapp中软键盘弹起,页面tabbar或顶部自定义navbar导航栏被撑起挤压的问题。如上图:支持h5+小程序+App端markdown解析渲染。上面则是演示了在App端+小程序端键盘弹......
  • 基于springboot+vue的漫画之家管理系统,附源码+数据库+论文+PPT,适合课程设计、毕业设计
    1、项目介绍随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代,“漫画之家”系统就是信息时代变革中的产物之一。任何系统都要遵循系统设计......
  • Vue(七)事件处理
    一、基本的事件处理<!DOCTYPEhtml><html><head><metacharset="utf-8"><title>基本的事件</title><scripttype="text/javascript"src="../js/vue.js"></script>......
  • java编程开发之若依vue框架 --- 后台开发
    分页实现前端基于element封装的分页组件 pagination(opensnewwindow)后端基于mybatis的轻量级分页插件pageHelper(opensnewwindow)#前端调用实现1、前端定义分页流程  #后台逻辑实现@PostMapping("/list")//定义/list接口,用于查询出列表@ResponseBody//返......
  • vue学习第25天 移动WEB开发----响应式布局
    目标:1)响应式原理2)使用媒体查询完成响应式导航3)使用Bootstrap的栅格系统4)使用Bootstrap的响应式工具5)完成阿里百秀首页案例 目录:1)响应式开发2)Bootstrap前端开发框架3)Bootstrap栅格系统4)阿里百秀首页案例  ......
  • vue学习第26天 xxxx响应式页面制作
    项目地址:后续添加 1、布局分析nav2列、article7列、aside3列 2、屏幕划分分析 移动端布局总结1、移动端主流方案 2、移动端技术选型1)流式布局(百分比布局)2)flex布局(推荐)3)rem适配布局(推荐)4)响应式布局建议:我们......
  • java编程开发之若依vue --- 部署
      部署的大致步骤0.配置环境,jdk下载安装配置环境变量,Mysql下一步就好记住用户名和密码,Redis下载win版本运行即可,Maven下载配置环境变量修改本地库存放位置,Node下一步就好设置下淘宝的镜像源。JDK>=1.8(推荐1.8版本)Mysql>=5.7.0(推荐5.7版本)Redis>=3.0Maven>......