跳转到内容

微信授权

刀刀

12/31/2024

0 字

0 分钟

职技网需要通过公众号为用户发送消息提醒,因此用到了微信网页授权。第一次尝试这个功能,在此记录从 0 开始的微信网页授权实现之路。

微信网页授权官网指路:微信网页开发/网页授权 .

思路剖析

根据官方文档的说法,翻译成大白话就是:

  1. 拿到需要发送消息提醒的公众号的 AppId 和授权后重定向的回调链接地址 redirect_uri 进行拼接。

  2. 根据文档的链接放置到对应的参数位置,location.href 路由跳转(地址分析见下方)。

  3. 跳转成功后路径上会有一个 code 值,获取到该 code 值调用后端的接口。

  4. 返回 openId 就算成功。

微信授权跳转地址示例如下所示:

txt
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=https%3A%2F%2Fchong.qq.com%2Fphp%2Findex.php%3Fd%3D%26c%3DwxAdapter%26m%3DmobileDeal%26showwxpaytitle%3D1%26vb2ctag%3D4_2030_5_1194_60&response_type=code&scope=snsapi_base&state=123#wechat_redirect

其中:

  • appid :公众号的唯一标识(必填)
  • redirect_uri :授权后重定向的回调链接地址, 需要使用使用 urlEncode 对链接进行处理(必填,本地如何获取见下方《本地环境》)
  • response_type :固定写死为 code 即可(必填)
  • scope :有两种参数可选。snsapi_base (不弹出授权页面,直接跳转,只能获取用户 openid );snsapi_userinfo (弹出授权页面,可通过 openid 拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息,需要用户授权)(必填)
  • #wechat_redirect :固定写死,前面不需要用 & 符号拼接(必填)

本地环境

根据上方分析可得知我们需要传递的参数,其余为固定写死, appId 可通过登录微信公众平台获取,只有 redirect_uri 重定向地址需要特别注意。

本地环境中,前端页面访问的路径为 http://192.168.0.20:8080 (即项目运行地址),但是这个是内网 IP 地址,外网无法访问,需要用到内网穿透,把内网映射到外网中,例如: http://8jybbr.natappfree.cc 映射到 http://192.168.0.20:8080 中。

内网穿透

本项目使用的是 natapp 这款软件,官网地址:natapp 。下面介绍一下如何实现内网穿透(也可以阅读官方教程文档,指路:NATAPP1 分钟快速新手图文教程)。

注册实名

没啥好讲的,注册账号,实名认证,绑定支付宝即可。

购买隧道与使用隧道

  1. 注册成功后登录,点击左侧购买隧道,选择免费隧道

  2. 修改名称、本地端口、隧道协议(本项目为 Web 协议,请根据自己的使用场景配合官方文档解释进行选择)

  3. 点击免费购买按钮购买隧道

  4. 点击左侧我的隧道,选择刚刚购买成功的隧道,点击配置按钮

  5. 修改本地地址为 127.0.0.1 ,端口为项目运行端口,勾选本地 Web 管理地址

  6. 点击修改,保存修改后复制其 autoToken

  7. 点击教程文档的 《使用本地配置文件 config.ini》 ,下载 config.ini (我是 windows 版本,因此下载对应的版本

  8. 打开下载好的 config.ini 文件,把第 6 步复制的 autoToken 粘贴到对应位置(其余设置不变)

  9. 下载客户端,解压安装

    注意:

    解压安装的 natapp 需要和 config.ini 处于同级目录下,否则无法运行。

  10. 双击解压安装的 natapp.exe ,就能获取到内网穿透的地址

配置

  1. 把链接复制给项目经理做了某种操作(用于文件校验域名,没接触不清楚他具体做了啥),返回一串字符,新建一个 txt 记事本粘贴,放到项目的 public 文件夹下。
  2. 此时访问链接,会提示:Invalid Host header 无效的请求头,去到 vue.config.js ,新建一个 devServer 对象,设置 disableHostCheck: true, ,重新运行项目。
  3. 成功访问(第一次访问会慢,需要等待)

获取 code

实现内网穿透后接下来就能通过获取到的地址放到对应位置传参获取到 code 值。

注意

redirect_url 需要使用 urlEncode 对链接进行处理

代码

vue
<script>
// 微信授权登陆地址
const WX_AUTH_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?";
// 重定向参数-固定写法
const REDIRECT = "#wechat_redirect";

export default {
  data() {
    return {
      model: {
        account: "",
        password: "",
        role: "",
        smsCode: "",
        code: "",
      },
      params: {
        appid: "wxbe0ffc4f85483b1e", // 公众号 APP ID
        redirect_uri: `${encodeURI("http://8jybbr.natappfree.cc/")}`, // 授权后重定向的回调链接地址, 使用 urlEncode 对链接进行处理
        response_type: "code", // 固定写法
        scope: "snsapi_base", // snsapi_base 静默授权获取 open id ;snsapi_userinfo 需要用户授权,获取详细信息
        // state:'code', // a-zA-Z0-9的参数值,最多128字节
      },
    };
  },
  created() {
    // 获取地址参数
    const params = new URLSearchParams(location.search);
    this.model.code = params.get("code");
    // 访问地址
    const access_url =
      WX_AUTH_URL + `${new URLSearchParams(this.params)}` + REDIRECT;
    // 这些需要判断没有 code 情况拉起授权登陆,有就结束放在重复拉起授权登陆
    if (!this.model.code) {
      location.href = access_url;
    }
  },
};
</script>

部分代码详解:

  • new URLSearchParams

    URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串,返回一个 URLSearchParams 对象。对象可以直接用在 for...of 结构中。

    其中,URLSearchParams.get() 可获取指定搜索参数的第一个值,如上方代码获取 code 值。

  • encodeURI

    encodeURI() 函数通过将特定字符的每个实例替换为一个、两个、三或四转义序列来对统一资源标识符 (URI) 进行编码 (该字符的 UTF-8 编码仅为四转义序列) 由两个 "代理" 字符组成)。

    参数:一个完整的 URI。

    返回值:一个新字符串,表示提供的字符串编码为统一资源标识符 (URI)。

线上环境

本项目线上域名地址为 http://www.zhijijob.com/client/#/ ,把 /#/ 去掉。

js
params: {
  appid: "wxbe0ffc4f85483b1e", // 公众号 APP ID
  redirect_uri: `${encodeURI("http://www.zhijijob.com/client")}`, // 授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理
},

打包部署,能够生效,即为成功。

调试

使用微信开发工具进行网页调试,选择公众号网页项目。

本地输入链接 localhost:8080 、在线输入在线域名地址,即可看到效果,返回相应的 code

注意

需要把自己添加为微信公众号的开发者才可以。