zoukankan      html  css  js  c++  java
  • H5 及 web 页面微信授权登录流程

    一、事先准备工作

    配置参数测试公众平台信息(测试号相关配置示例):

    1、打开公众平台的测试账号

    2、配置js接口安全域名

    3、扫码关注测试公众号

    4、修改网页授权地址

    配置授权回调的域名,至于什么是OAuth2.0,大家自行百度吧。这里的域名也要与上面的域名一致。配置成功会有通过安全监测的提示,这里不上截图了。

    注意:

    1、这里填写的是域名(是一个字符串),而不是URL,因此请勿加http://等协议头;
    2、授权回调域名配置规范为全域名,比如需要网页授权的域名为:www.qq.com,配置以后此域名下面的页面http://www.qq.com/music.html 、 http://www.qq.com/login.html 都可以进行OAuth2.0鉴权。
    但http://pay.qq.com 、 http://music.qq.com 、 http://qq.com无法进行OAuth2.0鉴权

    以上信息配置正确后。将参数传给后端(redirect_uri 需要 urlEncode 对链接进行处理后端更好处理)拼接起来。用返回的地址 window.locahost.href=‘xxxx’。调整新的地址并携带code

    二、授权登录

    1、微信登录的几种情况:

    • PC端:

      • PC端微信浏览器 -> 网页内嵌二维码方式(需要扫码,使用微信服务号的 appid 和 appsecret)

      • PC端其他浏览器 -> 跳转微信的扫码登录页面(需要扫码,使用微信开放平台注册的PC应用 appid 和 appsecret)

    • 移动端:

      • 微信客户端打开 -> 直接调用微信授权(不扫码,使用微信服务号的 appid 和 appsecret)

      • 其他手机浏览器打开 -> 跳转微信的扫码登录页面(需要扫码,使用微信开放平台注册的PC应用 appid 和 appsecret)

    2、区分是否是PC环境的方法:

    2.1、判断是PC环境还是移动环境是为了相应切换应用的布局,目前采用css媒体查询来做判断:

    /* 屏幕宽度小于等于1070像素时识别为移动端(1070像素是使推荐页常用情报站栏不现实滚动条的最小宽度) */
    @media screen and (max- 1070px) {
        /* 移动端布局css样式 */
    }
    /* 屏幕宽度大于1071像素识别为PC端 */
    @media screen and (min- 1071px) {
        /* PC端布局样式 */
    }

    2.2、js判断客户端是PC端还是移动端访问

    function IsPC(){  
         var userAgentInfo = navigator.userAgent;
         var Agents = new Array("Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod");  
         var flag = true;  
         for (var v = 0; v < Agents.length; v++) {  
             if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = false; break; }  
         }  
         return flag;  
      }
    if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
        //alert(navigator.userAgent);  
        window.location.href ="iPhone.html";
    } else if (/(Android)/i.test(navigator.userAgent)) {
        //alert(navigator.userAgent); 
        window.location.href ="Android.html";
    } else {
        window.location.href ="pc.html";
    };

    3、PC网页微信授权登录

    3.1、网页外链跳转的方式

    1)、请求后台的接口,会返回一个微信扫码的界面地址,使用js跳转过去即可

    wxlogin () {
           User.wxlogins().then(res => {
            console.log(res)
            window.location.href = res.result.url
          })
    },

    2)、用户在扫完码点击确定授权后,后台会拿到微信授权用户的信息后,会帮我们跳转到事先给后台重定向的地址页面(这里我是新建了一个空白页用来接收后台返回的数据),在地址后面后台会拼接一个token,我们拿到这个token,去获取用户信息,跳转到首页,即可完成登录

    let token = this.$route.query.token
        if (token) {
          this.getUserInfo().then(ures => {
            this.$router.push({
              name: 'home'
            })
          })
        }

    3.1、网页内嵌二维码方式

    1)、配置好下面相关参数,即可生成微信授权登录/绑定二维码,(注意:setWxerwma ()此方法需在mounted中调用)

    复制代码
     setWxerwma () {
          const s = document.createElement('script')
          s.type = 'text/javascript'
          s.src = 'https://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js'
          const wxElement = document.body.appendChild(s)
          wxElement.onload = function () {
            var obj = new WxLogin({
              id: '', // 需要显示的容器id
              appid: '', // 公众号appid wx*******
              scope: 'snsapi_login', // 网页默认即可
              redirect_uri: encodeURIComponent(''), // 授权成功后回调的url
              state: Math.ceil(Math.random() * 1000), // 可设置为简单的随机数加session用来校验
              style: 'black', // 提供"black"、"white"可选。二维码的样式
              href: '' // 外部css文件url,需要https
            })
          }
        },
    复制代码

    2)、后面的逻辑根据后台返回的数据来处理即可,同方法一步骤二类似

    或者也可以用下面步骤:

    1)、在页面中先引入如下JS文件(支持https):

    http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js

    2)、在需要使用微信登录的地方实例以下JS对象:

    var obj = new WxLogin({
      self_redirect:true,
      id:"login_container", 
      appid: "", 
      scope: "", 
      redirect_uri: "",
      state: "",
      style: "",
      href: ""
    });

    参数说明:

    redirect_uri 为回调链接,由后端提供给前端

    引入远程js的方法:

    mounted () {
      const wxJs = document.createElement('script')
      wxJs.type = 'text/javascript'
      wxJs.src = 'http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js'
      document.body.appendChild(wxJs)
    },
    beforeRouteLeave (to, from, next) {
      document.body.removeChild(wxJs)
      next()
    }

    tips:用户扫码授权后,进入回调页面,由后端完成与微信开放平台间的数据请求后,重定向回到前端页面链接,链接后面带上参数,然后前端截取链接后面的参数,请求后端接口,进行登录操作,例子如下:

    beforeRouteEnter (to, from, next) {
      next(vm => {
        if (JSON.stringify(vm.$route.query) === '{}') {
          console.log('没有参数')
        } else {
          // 使用this.$route.query截取链接后面的参数,请求后端接口
          vm.pWxLogin()
        }
      })
    },

    4、移动端微信授权登录

    静默授权的意思是用户无感知的获取用户信息,不需要用户有任何的操作动作,注意静默授权只能获取到用户的openId。并不能获取到用户的其他信息。

    非静默授权的意思是需要用户去操作,点击同意按钮,也就是说,如果产品要求是非静默授权,那么前端会弹起用户授权的按钮,待用户同意之后,就可以获取到用户的openId,个人信息,关注信息等相关内容。

    注:静默授权和非静默授权的区别在于调用的接口的 scope 字段是 snsapi_base 还是 snsapi_userinfo 

    4.1、创建一个按钮,点击触发事件,跳转到微信授权页面

    wxlogin () {
          window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${this.appid}&redirect_uri=${this.url}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
    }
    //this.appid 公众号APPID  this.url  用户点击授权后,会跳转到后台帮我们重定向的页面(这里我是新建了一个空白页,专门接收code)

    其中:

    appid:是应用的appid
    redirect_uri:是指回跳的url
    response_type:只写code
    scope:表示授权的作用域,多个可以用逗号隔开,snsapi_base 表示静默授权,snsapi_userinfo 表示非静默授权
    state:用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验

    4.2、页面会自动跳转到类似以下地址,在重定向的页面拿到给我们返回的 code,会拼接在URL后面

    https://www.test.com/?code=021MZkll2DUtR63EuUnl21BZPv0MZklE&state=STATE

    注意:如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。若用户禁止授权,则重定向后不会带上code参数,仅会带上state参数redirect_uri?state=STATE

    4.3、通过code换取网页授权access_token

    在业务代码中,用JS获取code参数,然后访问以下地址:

    https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

    其中:

    • appid:应用的appid,
    • secret: 应用密钥AppSecret,
    • code:上一步中获取到的code
    • grant_type:值为authorization_code

    成功后的返回数据如下:(主要是拿access_token和openid字段)

    { 
        "access_token":"ACCESS_TOKEN",
        "expires_in":7200,
        "refresh_token":"REFRESH_TOKEN",
        "openid":"OPENID",
        "scope":"SCOPE" 
    }

    4.4、用access_token 和openid获取用户信息

    用access_token和openid字段访问以下地址:

    https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

    其中:

    • access_token:上一步的access_token
    • openid:上一步的openid

    返回值如下:

    {   
        "openid":" OPENID",
        "nickname": NICKNAME,
        "sex":"1",  //
        "province":"PROVINCE"
        "city":"CITY",
        "country":"COUNTRY",
        "headimgurl":    "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
        "privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
        "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
    }

    错误时微信会返回JSON数据包如下(示例为openid无效):

    {"errcode":40003,"errmsg":" invalid openid "}

    值得注意的地方

      用户管理类接口中的“获取用户基本信息接口”,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。

      网页授权获取用户基本信息也遵循UnionID机制。即如果开发者有在多个公众号,或在公众号、移动应用之间统一用户帐号的需求,需要前往微信开放平台(open.weixin.qq.com)绑定公众号后,才可利用UnionID机制来满足上述需求。

      UnionID机制的作用说明:如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为同一用户,对同一个微信开放平台下的不同应用(移动应用、网站应用和公众帐号),unionid是相同的。

      尤其注意:由于公众号的secret和获取到的access_token安全级别都非常高,必须只保存在服务器,不允许传给客户端。后续刷新access_token、通过access_token获取用户信息等步骤,也必须从服务器发起。

    参阅官方文档: https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html

  • 相关阅读:
    Springboot 之 自定义配置文件及读取配置文件
    SQLSERVER系统视图 sql server系统表详细说明
    MySQL Workbench建表时 PK NN UQ BIN UN ZF AI 的含义
    使用Ecplise git commit时出现"There are no stages files"
    maven添加sqlserver的jdbc驱动包
    java将XML文档转换成json格式数据
    java将XML文档转换成json格式数据
    cannot be resolved. It is indirectly referenced from required .class files
    org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.util.Date from String value '2012-12-12 12:01:01': not a valid representation (error: Can not parse date "2012-12-
    @Autowired注解和静态方法 NoClassDefFoundError could not initialize class 静态类
  • 原文地址:https://www.cnblogs.com/joe235/p/14656225.html
Copyright © 2011-2022 走看看