微信网页登录逻辑与实现方法

现在的网站开发,都绕不开微信登录(毕竟微信已经成为国民工具)。虽然文档已经写得很详细,但是对于没有经验的开发者还是容易踩坑。

所以,专门记录一下微信网页认证的交互逻辑,也方便自己日后回查:

  1. 加载微信网页sdk
  2. 绘制登陆二维码:新tab页面绘制 / 本页面iframe绘制
  3. 用户扫码登陆,前端跳入回调网址
  4. 回调网址进一步做逻辑处理,如果是页内iframe绘制二维码,需要通知顶级页

微信网页SDK加载

在多人团队协作中,加载资源的代码需要格外小心。因为可能会有多个开发者在同一业务逻辑下调用,这会造成资源的重复加载。

处理方法有两种,第一种是对外暴露多余接口,专门check是否重复加载。但是考虑到调用者每次在加载前,都需要显式调用check()方法进行检查,难免会有遗漏。

所以采用第二种方法--设计模式中的缓存模式,代码如下:

// 备忘录模式: 防止重复加载
export const loadWeChatJs = (() => {
 let exists = false; // 打点
 const src = '//res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js'; // 微信sdk网址

 return () => new Promise((resolve, reject) => {
  // 防止重复加载
  if(exists) return resolve(window.WxLogin);

  let script = document.createElement('script');
  script.src = src;
  script.type = 'text/javascript';
  script.onerror = reject; // TODO: 失败时候, 可以移除script标签
  script.onload = () => {
   exists = true;
   resolve(window.WxLogin);
  };
  document.body.appendChild(script);
 });
})();

绘制登陆二维码

根据《微信登陆开发指南》,将参数传递给window.WxLogin()即可。

// 微信默认配置
const baseOption = {
 self_redirect: true, // true: 页内iframe跳转; false: 新标签页打开
 id: 'wechat-container',
 appid: 'wechat-appid',
 scope: 'snsapi_login',
 redirect_uri: encodeURIComponent('//1.1.1.1/'),
 state: '',
};

export const loadQRCode = (option, intl = false, width, height) => {
 const _option = {...baseOption, ...option};

 return new Promise((resolve, reject) => {
  try {
   window.WxLogin(_option);
   const ele = document.getElementById(_option['id']);
   const iframe = ele.querySelector('iframe');
   iframe.width = width? width : '300';
   iframe.height = height? height : '420';
   // 处理国际化
   intl && (iframe.src = iframe.src + '&lang=en');
   resolve(true);
  } catch(error) {
   reject(error);
  }
 });
};

在需要使用的业务组件中,可以在周期函数componentDidMount调用,下面是demo代码:

componentDidMount() {
  const wxOption = {
    // ...
  };
  loadWeChatJs()
    .then(WxLogin => loadQRCode(wxOption))
    .catch(error => console.log(`Error: ${error.message}`));
}

回调网址与iframe通信

这一块我觉得是微信登陆交互中最复杂和难以理解的一段逻辑。开头有讲过,微信二维码渲染有2中方式,一种是打开新的标签页,另一种是在指定id的容器中插入iframe。

毫无疑问,第二种交互方式更友好,因为要涉及不同级层的页面通信,代码处理也更具挑战。

为了方便说明,请先看模拟的数据配置:

// redirect 地址会被后端拿到, 后端重定向到此地址, 前端会访问此页面
// redirect 地址中的参数, 是前端人员留给自己使用的; 后端会根据业务需要, 添加更多的字段, 然后一起返回前端
const querystr = '?' + stringify({
 redirect: encodeURIComponent(`${window.location.origin}/account/redirect?` + stringify({
  to: encodeURIComponent(window.location.origin),
  origin: encodeURIComponent(window.location.origin),
  state: 'login'
 })),
 type: 'login'
});

const wxOption = {
 id: 'wechat-container',
 self_redirect: true,
 redirect_uri: encodeURIComponent(`//1.1.1.1/api/socials/weixin/authorizations${querystr}`) // 微信回调请求地址
};

前后端、微信服务器、用户端交互逻辑

按照上面的配置,我描述一下前端、用户端、微信服务器和后端交互的逻辑:

  • 前端根据wxOption加载了二维码,所有信息都放在了二维码中。同时监听微信服务器的消息。
  • 用户手机扫码,通知微信服务器确定登陆。
  • 微信服务器接受到用户的扫码请求,转发给前端。
  • 前端收到微信服务器传来消息,根据wxOption的redirect_uri参数,跳转到此url地址。注意:
    • 这个接口地址是后端的,请求方式是GET
    • 前端通过拼接params携带参数
    • 地址会被拼接微信服务器传来的一个临时token,用于交给后端换取用户公众密钥
  • 后端接收到/api/socials/weixin/authorizations${querystr}的请求,decode解码querystr中的信息。然后向微信服务端请求用户公众密钥。根绝前后端的约定(demo中用的是redirect字段),重定向到前端指定的redirect字段,并且拼接用户公众密钥等更多信息。
  • 前端知悉重定向,跳到重定向的路由(demo中用的是/account/redirect)
  • 在对应的路由处理后端传来的用户密钥等数据即可
  • 至此,微信认证的四端交互逻辑完成

跨Iframe通信

前面流程走完了,现在的情况是页面中iframe的二维码区域,已经被替换成了/account/redirect?...的内容。

为了实现通信,需要在页面的周期中监听message事件,并在组件卸载时,卸载此事件:

componentDidMount() {
 // ... ...

 window.addEventListener('message', this.msgReceive, false);
}

componentWillUnmount() {
 window.removeEventListener('message', this.msgReceive);
}

msgReceive(event) {
 // 监测是否是安全iframe
 if(!event.isTrusted) {
  return;
 }
 console.log(event.data); // 获取iframe中传来的数据, 进一步进行逻辑处理
}

而在/account/redirect?...路由对应的组件中,我们需要解析路由中的params参数,按照业务逻辑检查后,将结果传递给前面的页面:

componentDidMount() {
  // step1: 获取url中params参数
  const querys = getQueryVariable(this.props.location.search);
  // step2: 检查querys中的数据是否符合要求 ...
  // step3: 向顶级页面传递消息
  return window.parent && window.parent.postMessage('data', '*');
}

至此,微信网页认证的流程完成。

更多:关于iframe通信的更多细节,请查看MDN的文档

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • ajax 实现微信网页授权登录的方法

    项目背景 因为项目采用前后端完全分离方案,所以,无法使用常规的微信授权登录作法,需要采用 ajax 实现微信授权登录. 需求分析 因为本人是一个phper ,所以,微信开发采用的是 EasyWeChat ,所以实现的方式是基于EW的. 其实实现这个也麻烦,在实现之前,我们需要了解一下微信授权的整个流程. 引导用户进入授权页面同意授权,获取code 通过code换取网页授权access_token(与基础支持中的access_token不同) 如果需要,开发者可以刷新网页授权access_toke

  • 微信网页 第三方登录原理详解

    微信开放平台和公众平台的区别 1.公众平台面向的时普通的用户,比如自媒体和媒体,企业官方微信公众账号运营人员使用,当然你所在的团队或者公司有实力去开发一些内容,也可以调用公众平台里面的接口,比如自定义菜单,自动回复,查询功能.目前大多数微信通过认证之后,都在做这个事情. 2.开放平台面向的开发者和第三方独立软件开发商.我觉得开发平台最大的开放就是微信登录.当年腾讯没有花大力气去做统一登录这个事情,导致目前各个网站都要弄一套登录机制.好在他们现在认清了局势.开发者或软件开发商,通过微信开放提供的平

  • 微信网页登录逻辑与实现方法

    现在的网站开发,都绕不开微信登录(毕竟微信已经成为国民工具).虽然文档已经写得很详细,但是对于没有经验的开发者还是容易踩坑. 所以,专门记录一下微信网页认证的交互逻辑,也方便自己日后回查: 加载微信网页sdk 绘制登陆二维码:新tab页面绘制 / 本页面iframe绘制 用户扫码登陆,前端跳入回调网址 回调网址进一步做逻辑处理,如果是页内iframe绘制二维码,需要通知顶级页 微信网页SDK加载 在多人团队协作中,加载资源的代码需要格外小心.因为可能会有多个开发者在同一业务逻辑下调用,这会造成资

  • Vue3项目中优雅实现微信授权登录的方法

    目录 前言 准备 实现思路 上代码 总结 前言 微信授权登录是做微信公众号开发一直绕不开的话题,而且整个授权登录流程的实现,是需要前后端配合一起完成的.在过去前后端还未分离的年代,也许我们前端并不需要太过关心授权的具体实现.然而现在都2021年了,前后端分离的架构大行其道,如何在前后端分离的情况下实现微信授权登录就成了今天要探讨的重点问题. 准备 首先,我们还是需要先梳理下微信授权整个流程是怎样的,这里我就直接将官方文档搬来: 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制

  • .NET Core企业微信网页授权登录的实现

    目录 1.开发前准备 参数获取 2.企业微信OAuth2接入流程 3.构造网页授权链接 4. 调用代码部分 4.1 appsettings配置 4.2 配置IHttpClientFactory调用微信客户端 4.3 类准备 4.4方法准备 4.5调用 5.截图 1.开发前准备 参数获取 corpid 每个企业都拥有唯一的corpid,获取此信息可在管理后台“我的企业”-“企业信息”下查看“企业ID” secret secret是企业应用里面用于保障数据安全的“钥匙”,每一个应用都有一个独立的访问

  • C#实现的微信网页授权操作逻辑封装示例

    本文实例讲述了C#实现的微信网页授权操作逻辑封装.分享给大家供大家参考,具体如下: 一.微信网页授权登录 前提: 1.已经获取的接口权限,如果是测试账号就已经有权限了 2.配置接口的授权域名 更多说明可以参考方倍工作室:http://www.cnblogs.com/txw1958/p/weixin71-oauth20.html 或者官网API:http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.html 步骤: 1.用

  • 详解java实现简单扫码登录功能(模仿微信网页版扫码)

    java实现简单扫码登录功能 模仿微信pc网页版扫码登录 使用js代码生成qrcode二维码减轻服务器压力 js循环请求服务端,判断是否qrcode被扫 二维码超时失效功能 二维码被扫成功登录,服务端产生sessionId,传到页面使用js保存cookie 多线程 生成qrcode相关js jquery.qrcode.js 代码 页面div <div class="pc_qr_code"> <input type="hidden" id="

  • springboot 微信授权网页登录操作流程

    操作流程 假设你已经有自己的域名,因为微信公众号和微信回调都需要域名 先看看官方给的文档 根据官方文档,主要流程如下: (1)引导用户进入授权页面同意授权,获取code (2)通过code换取网页授权access_token(与基础支持中的access_token不同) (3)刷新access_token(如果有需要) (3)通过网页授权access_token和openid获取用户基本信息 提示:以下是本篇文章正文内容,下面案例可供参考 编写微信授权方法和获取用户信息方法 二.使用步骤 获取微

  • php版微信自动登录并获取昵称的方法

    本文实例讲述了php版微信自动登录并获取昵称的方法.分享给大家供大家参考,具体如下: 微信自动登录并获取昵称是可以通过api接口来获取的也是通过微信开放的接口来实现了,下面我们一起来看一个例子 仅记录:微信获取昵称自动登录 经过反复几次验证,发现我这个方法有缺陷: 微信内 未关注进入网站,无法获得昵称. 关注后用我这个方法可以获得昵称. 是否是因为第一次生成openid 所以还未生成昵称?待测试. /** * 获取当前页面完整URL地址 */ function get_url() { $sys_

  • Android实现使用微信登录第三方APP的方法

    本文实例讲述了Android实现使用微信登录第三方APP的方法.分享给大家供大家参考,具体如下: 使用微信登录APP,免去注册过程,现在已经有很多的类似应用了.集成该功能过程不复杂,但还是有一些地方需要注意的. 开始之前,需要做下面的准备工作. 1.到微信开放平台注册你的APP,并申请开通微信登录的权限.参考这里: https://open.weixin.qq.com// 2.下载Android SDK和签名查看工具,请参考: https://open.weixin.qq.com/cgi-bin

随机推荐