【开发心得】微信网页应用授权登录

微信登录官方资料:

准备工作 | 微信开放文档

第三方参考资料:

vue 微信扫码登录嵌入方式及开发踩的坑点_范特西是只猫的博客-CSDN博客_微信网页扫码登录开发文档

说明:

1. 微信官方有两种对外能力,分别是 网站应用 与 微信开放平台,这两个服务都有授权登录,注意,我们使用的是前者,故需要的scope 是 

   snsapi_login. 而微信开放平台是供给小程序,公众号等使用的。权限是snsapi_base 和 snsapi_userinfo

   网站应用: 需要300块开通费用与企业授权。

   开放平台: 需要申请开发者账号及授权,并且提供测试账号。

2. 微信登录对接方式有两种

   (1) 直接根据appid与scope等新开一个网页,很多网站都使用该方案,缺点: 需要弹出一个单独的页面,用户体验不够友好。

   (2) 嵌入方式。优点,充分自定义。缺点: 对接比较繁琐。

 对接步骤:

参数详解(具体以官方为准):

appid 应用id,微信接入申请时获得
scope:权限范围 默认snsapi_login
state: 自定义状态保持
login_tupe: jssdk
stype: "black"、"white"可选,默认为黑色文字描述
​
self_redirect: true:手机点击确认登录后可以在 iframe 内跳转到 redirect_uri,false:手机点击确认登录后可以在 top window 跳转到 redirect_uri。默认为 false。
​
redirect_uri: 重定向地址,需要进行UrlEncode
href: 自定义样式链接,第三方可根据实际需求覆盖默认样式
​
注意:
1. href base64加密后的样式
2. redirect_uri 参数错误 申请时,配置的重定向域名和当前使用域名不一致,或者scope不对.
​

(3). 创建一个单独的direct页面,回调用

修改route.js 增加

{
  path: '/oauth',
  meta: {title: "登录跳转", noCache: true},
  component: () => import('@/views/oauth'),
  hidden: true,
},

路由控制,放行该路由白名单:

const whiteList = ['/login', '/oauth']; // no redirect whitelist

direct页面

<template>
  <div>
    <div class="loader">授权中...</div>
  </div>
</template>
​
<script>
export default {
  name: "oauth",
  data() {
    return {
      loading: true,
    }
  },
  mounted() {
    let code = this.$route.query.code;
    let bindState = this.$route.query.state;
    let wechatInfo = {
      code,
      bindState
    }
    window.parent.postMessage(wechatInfo, '*');
  },
  methods: {
​
  }
}
</script>
​
<style scoped>
body{
  background: #56b4ab;
}
.loader,
.loader:before,
.loader:after {
  background: #FFF;
  /*
  * load1:执行的动画名
  * 1s:执行一秒
  * infinite:执行无限次
  * ease-in-out:动画以低速开始和结束
  */
  animation: load1 1s infinite ease-in-out;
  width: 1em;
  height: 4em;
}
.loader:before,
.loader:after {
  position: absolute;
  top: 0;
  content: '';
}
.loader:before {
  left: -1.5em;
}
.loader {
  text-indent: -9999em;
  margin: 40% auto;
  position: relative;
  font-size: 11px;
  /* 延时0.16s */
  animation-delay: 0.16s;
}
.loader:after {
  left: 1.5em;
  /* 延时0.32s */
  animation-delay: 0.32s;
}
@keyframes load1 {
  0%,
  80%,
  100% {
    box-shadow: 0 0 #FFF;
    height: 4em;
  }
  40% {
    /* 实现上部拉伸 */
    box-shadow: 0 -2em #ffffff;
    /* 实现下部拉伸 */
    height: 5em;
  }
}
</style>

direct页面获取重定向后携带的code和自定义状态,发送消息给父页面

mounted() {
    let code = this.$route.query.code;
    let bindState = this.$route.query.state;
    let wechatInfo = {
      code,
      bindState
    }
    window.parent.postMessage(wechatInfo, '*');
}

 父页面监听:

mounted: function () {
  // 开启微信登录
  if (this.useWechatLogin) {
    window.addEventListener('message', this.receiveMessage);
  }
  this.loginUsernamePassword();
},
destroyed() {
  window.removeEventListener('message', this.receiveMessage);
}

二维码核心页面:

<template>
  <div>
    <iframe sandbox="allow-scripts allow-top-navigation allow-same-origin" scrolling="no" width="500" height="300" frameBorder="0"
            allowTransparency="true" :src="setSrc" ref="iframe" v-if="showIframe"></iframe>
<!--    <iframe sandbox="allow-scripts allow-top-navigation" scrolling="no" width="500" height="300" frameBorder="0" allowTransparency="true" :src="setSrc"></iframe>-->
  </div>
</template>
​
<script>
export default {
  methods: {
  },
  data () {
    return {
      // src: 'https://open.weixin.qq.com/connect/qrconnect?appid=wxe1f5def243e0390b&scope=snsapi_login&redirect_uri=https://abstest.tenpay.com/abs/author/callBack.do&state=0001&login_type=jssdk&self_redirect=default&style=black&href=./wx.css',
      // https://open.weixin.qq.com/connect/qrconnect?appid=wxe1f5def243e0390b&scope=undefined&redirect_uri=undefined&state=&login_type=jssdk&self_redirect=default&style=black&href=
    }
  },
  computed : {
    setSrc () {
      var _url = 'https://open.weixin.qq.com/connect/qrconnect?appid='+ this.appid
      // var _url = 'https://open.weixin.qq.com/connect/qrconnect?appid='+ this.appid
        + '&scope=' + this.scope
        + '&redirect_uri='  + this.redirect_uri
        + '&state=' + this.state
        + '&login_type=' + this.login_type
        + '&style=' + this.theme
        + '&self_redirect=' + this.self_redirect
        + '&href=' + this.href;
      return _url;
    },
  },
  props:{
    //应用唯一标识,在微信开放平台提交应用审核通过后获得
    appid : String,
    //应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可
    scope : String,
    //重定向地址,需要进行UrlEncode
    redirect_uri : String,
    //用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验
    state : {
      type : String,
      default: ''
    },
    //提供"black"、"white"可选,默认为黑色文字描述。详见文档底部FAQ
    theme : {
      type : String,
      default: 'black'
    },
    // 自定义样式链接,第三方可根据实际需求覆盖默认样式。详见文档底部FAQ
    href : {
      type : String,
      default: ''
    },
    // true:手机点击确认登录后可以在 iframe 内跳转到 redirect_uri,false:手机点击确认登录后可以在 top window 跳转到 redirect_uri。默认为 false。
    self_redirect : {
      type : Boolean,
      default: true
    },
    // sdk的扩展字符串,但是在这里就默认了jssdk,暂时不建议修改
    login_type : {
      type : String,
      default: 'jssdk'
    },
    showIframe: {
      type: Boolean,
      default: true
    }
  },
}
</script>

测试:

1. 直接部署测试。如果有条件的话。

2. 本地映射成申请时候填写的域名。 百度搜索 Windows hosts修改,或者 Mac host修改。根据开发环境来。(测试服务器也类似)

3. 如果后台登记的是https服务的话,本地webpack需要做下配置:

https 开启 并且设置为跨域.

vue.config.js

  devServer: {
    port: 443,
    hot: true,
    disableHostCheck: true,
    https: true,
    proxy: {
      '/api': { // 凡是接口中后面域名中带有api的 , 框架都会进行一个代理转发
        target: 'http://xxxxxx/api',  // 后端提供的接口地址
        changeOrigin: true, // 开启跨域代理
      }
    }
  },

相信完整的看完本文,应该就能完成了,不方便公开全部代码,有问题欢迎私信交流讨论。

posted @ 2022-07-29 18:45  虹梦未来  阅读(18)  评论(0编辑  收藏  举报  来源