vue-pc 微信网页授权-扫码登录授权

写在前面


本次微信登录是基于vue全家桶+element-ui开发的

首先先理清楚微信网页授权登录的思路:

1,在微信开放平台注册开发者账号,并且拥有一个已审核通过的网站应用,获取相应的appid和appsecert,申请微信登录且通过审核后,就可以开始了。
2,配置微信的第三方回调域名,只有设置了回调域名,才能在扫码后微信处理完成回调到你当前的网站,在带给你code,然后在将code传给后台接受需要的消息。
3,具体的请移步官方文档网站应用微信登录功能
4,我在这里主要具体介绍在vue里边如何做这个登录的,毕竟这个我折腾了好半天,必须记录一下,方便以后学习。

接下来就是如何在vue项目中做的开发。

通过官网不难看出微信提供了两种获取扫描二维码的方式,一种是直接打开配置好的的链接,另一种是在自己的网页内渲染这个二维码。这里着重介绍在自己的网站内打开二维码的方式,这里是为了更好地用户体验。

最重要的处理是在main.js------permission.js中,处理权限的路由跳转比较谨慎,其他的直接使用微信提供的方法就好了。

第一步:在项目中vue是在index.html引入微信的js文件

<script src="http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js"></script>

第二步:在你需要的页面中渲染二维码

这里记录一下我踩的坑

一开始我是直接将二维码放在el-dialog中的,但是一直未渲染出来,所以就改为自己写了一个弹窗

当你使用微信授权时候,肯定是希望在某个页面授权等微信的授权回来再跳到某个页面,这个时候就需要在该页面判断如果有code就做调用接口做你想做的操作,如果没有就走你原来页面的正常流程。

切记一点:代码注释里边有写:::当你绑定成功之后需要删除url后边的微信回调的code,如果不做处理那就在路由守卫里边一直进入这个页面,然后陷入无限的死循环。
<template>
    <div v-show="Wechat_authorized_login" class="wx_dialog_toiast">
           <!-- 承载二维码容器 -->
      <div class="wx_dialog_toiast_delltet" id="login_container"></div>
      <div class="wx_dialog_button_delete" @click="close_wchat_qrcode">
        <i class="el-icon-circle-close" style="color: red; font-size: 70px"></i>
      </div>
    </div>
</template>
<script>
export default {
  data() {
    return {
       Wechat_authorized_login:false,
    };
  },
  created() {
    this.Get_wechat_callback_information();
  },
 mounted() {
    this.get_wx_qrcode();   //获取微信的登录二维码
  },
  methods: {
    get_wx_qrcode(){
      //从微信的开发文档不难看出回调域名需要经过encodeURIComponent处理
                      let call_back_domain_name = window.location.href,
                       domain_name_length = call_back_domain_name.indexOf("#") - 1,
                       DDNS = call_back_domain_name.substring(0, domain_name_length),
                       DDNS_resolution = encodeURIComponent(DDNS);
         var obj = new WxLogin({
           self_redirect: false,
           id: "login_container",       //需要承载二维码的容器id  
           appid: "wx795be91b97e81d8c",
           scope: "snsapi_login",     //网页授权,目前网页只有这一种方式,静默授权
           redirect_uri: DDNS_resolution,     //回调域名
          state: Math.random(),
          style: "white",
          href: "",
    });

           },
  // 获取微信回调信息并且绑定账号
    Get_wechat_callback_information() {
      let Wechat_return_code = window.location.href;
     //获取微信回调的code
      let wx_parseUrl = qs.parse(Wechat_return_code.split("?")[1]); 
    //因为这里的需求绑定账号时需要发送验证码,所以暂存本地
      let wx_code_url = localStorage.getItem("QRCODEWX");
      let analysis_wx_code_url = JSON.parse(wx_code_url);
    //当有验证码并且微信回调了code的时候再去做绑定操作。
      if (wx_parseUrl.code && wx_code_url != null) {
        let parse_bind_params = {
          code: wx_parseUrl.code,
          codeUuid: analysis_wx_code_url.codeUuid, 
          codeValue: analysis_wx_code_url.codeValue,
          phone: analysis_wx_code_url.phone,
        };
        withdrawAccountBinding(parse_bind_params).then((response) => {
          this.$message({
            message: response.msg,
            type: "success",
            center: true,
            duration: "2000",
          });
          //绑定成功之后需要删除之前存储的验证码和验证uuid.这样方便在导航守卫里边做操作
          localStorage.removeItem("QRCODEWX");
         //当你绑定成功之后需要删除url后边的微信回调的code,如果不做处理那就在路由守卫里边一直进入这个页面,然后陷入无限的死循环。
          if (Wechat_return_code.indexOf("?") != -1) {
            Wechat_return_code = Wechat_return_code.replace(/(\?|#)[^'"]*/, "");
            window.history.pushState({}, 0, Wechat_return_code);
          }
    //删除之后再次更新路由地址,以确保路由地址没有code。保证不会进入死循环
          this.$router.replace({
            path: "/agentManger/agentMoneyList",
          });
          this.is_show_withdraw_function(); //是否显示资金余额与提现账号
          this.Obtain_withdrawal_account_number(); //首先获取提现账号的所有信息
        });
      }
    },
    },
};
</script>

<style lang='scss' scoped>
.wx_dialog_toiast {
  position: fixed;
  top: 0px;
  left: 0px;
  width: 100%;
  height: 100%;
  z-index: 9854647;
  background: rgba($color: #000000, $alpha: 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  .wx_dialog_toiast_delltet {
    width: 500px;
    height: 500px;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .wx_dialog_button_delete {
    position: absolute;
    right: 0px;
    top: 0px;
    height: 100px;
    width: 100px;
    display: flex;
    justify-content: center;
    align-items: center;
  }
}
</style>

第三步: main.js------permission.js在路由守卫处做处理,这里是重点

这里是做的权限处理,路由导航守卫

import router from './router'
import store from './store'
import {
  Message
} from 'element-ui'
import NProgress from 'nprogress' // 页面顶部的加载进度条
import 'nprogress/nprogress.css' // progress bar style
import {
  getToken
} from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'
import {
  getRouters
} from '@/api/user'
import {
  filterAsyncRouter
} from '@/store/modules/permission'
import qs from "qs";

NProgress.configure({
  showSpinner: false
}) // NProgress Configuration

const whiteList = ['/login'] // no redirect whitelist

router.beforeEach(async (to, from, next) => {
//首先拿到当前路由地址
const wx_url =window.location.href;  
const parseUrl = qs.parse(wx_url.split('?')[1]);
console.log(wx_url);
var reject_url_wx = "";
var reject_code_query = parseUrl.code;
//这一步就是第二步所说的存在本地的验证码的信息,这里的操作就是如果有验证码并且有微信回调的code,那就进入当前的页面,如果没有那就进入正常的路由
let wx_code_url = localStorage.getItem("QRCODEWX");
if (wx_code_url == null) {
  reject_url_wx = "";
}else{
  if (parseUrl.code && parseUrl.state) { 
    reject_url_wx = `/agentManger/agentMoneyList?${qs.stringify(parseUrl)}`;
  }else{   
    reject_url_wx = "";
  }
}

  // start progress bar   
  NProgress.start()

  // set page title
  document.title = getPageTitle(to.meta.title)     

  // determine whether the user has logged in
  const hasToken = getToken()

  if (hasToken) {


    if (to.path === '/login') {

      // if is logged in, redirect to the home page

        next({
          path: '/'
        })
        NProgress.done()
    
    } else {
      const hasRoles = store.getters.roles && store.getters.roles.length > 0
      if (hasRoles) {
        // next()
        if (reject_url_wx == "") {
          next();
        }else{
       //这里是重点,为了防止beforeach进入死循环的操作
          if (to.path == "/agentManger/agentMoneyList") {
              next()    
            }else{ 
               next({path:'/agentManger/agentMoneyList',query:{code:reject_code_query}})
            }
        }

      } else {
        try {
          store.dispatch('user/getInfo').then(res => {
            loadMenus(next, to)
          }).catch(err => {
            console.log(err)
          })
        } catch (error) {
          await store.dispatch('user/resetToken')
          Message.error(error || 'Has Error')
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    }

  } else {
    /* has no token*/

    if (whiteList.indexOf(to.path) !== -1) {
      // in the free login whitelist, go directly
      next()
    } else {
      // other pages that do not have permission to access are redirected to the login page.
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})

export const loadMenus = (next, to) => {
  getRouters().then(res => {
    const data = res.data
    const asyncRouter = filterAsyncRouter(data)
    const redirectPath = asyncRouter[0].children && asyncRouter[0].children.length > 0 ?
      asyncRouter[0].children[0].path :
      asyncRouter[0].path

    asyncRouter.unshift({
      path: '/',
      redirect: redirectPath,
      hidden: false
    })
    asyncRouter.push({
      path: '*',
      redirect: '/404',
      hidden: true
    })

    store.dispatch('GenerateRoutes', asyncRouter).then(() => { // 存储路由
      router.addRoutes(asyncRouter) // 动态添加可访问路由表
      next({
        ...to,
        replace: true
      })
    })
  })
}

router.afterEach(() => {
  // finish progress bar
  NProgress.done()
})


结束语

到此,就可以完美的做到微信扫码授权登录了,以后再也不用愁了,后续如果有变更还会更新,继续学习。

更新

这里还用到之前没用过得技术-------删除url后边的参数

  let Wechat_return_code = window.location.href;
          if (Wechat_return_code.indexOf("?") != -1) {
            Wechat_return_code = Wechat_return_code.replace(/(\?|#)[^'"]*/, "");
            window.history.pushState({}, 0, Wechat_return_code);
          }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容