微信公众号全流程

news2024/12/23 20:04:57
  1. 申请公众号(服务号+已认证)
  2. web开发者工具中绑定开发人员(该开发人员需要关注1中申请的公众号)
  3. 基本配置
    3.1 服务器配置
    URL:验证服务器(后端写的验证服务器的接口)
    后端代码:egg.js
yarn add crypto-js

const SHA1 = require('crypto-js/sha1');
	async checkSign() {
	    const { ctx, app } = this;
	    const token = app.config.wechat_config.token; // 替换为你的微信公众号的Token
	    const { signature, timestamp, nonce, echostr } = ctx.query;
	    const shasum = SHA1([ token, timestamp, nonce ].sort().join('')).toString();
	    if (shasum === signature) {
	      return echostr;
	    }
	    return 'Invalid signature';
	  }

	async validate() {
	    const { ctx, service } = this;
	    ctx.body = await service.wx.checkSign();
	}

Token: 可以自定义(后续跟微信要信息的时候使用,验证服务器的时候也需要)
服务器配置什么时候启用:
一些自定义的跟微信相关的操作:例如支付流程,自定义推送等

3.2 自定义菜单(公众号底部的菜单配置)
3.2.1 可以配置完成的带公众号基础信息的url
例如:https://open.weixin.qq.com/connect/oauth2/authorize? appid=wx8a432443c4997c0c&redirect_uri=http://gzh-dev.nangaoyun.com/equip/wechatAuth/menu?type=work&response_type=code&scope=snsapi_userinfo&state=123&connect_redirect=1#wechat_redirect
3.2.2 也可配置访问页面的地址
例如:http://www.youtianchen.cn

  1. 网页授权
    4.1 用户同意授权,获取token
    这个code是我们点击自定义菜单时,微信内部重定向到一个url,这个url里带了code

获取code(前端代码)

import { history } from "umi";
import { doFetch } from "./doFetch"; //发送请求的方法,封装了一下而已

//从网页地址中获取code
function getQueryVariable(variable) {
  var query = window.location.search.substring(1);
  var vars = query.split("&");
  for (var i = 0; i < vars.length; i++) {
    var pair = vars[i].split("=");
    if (pair[0] == variable) {
      return pair[1];
    }
  }
  return false;
}

export default function getUserinfo(props, fn) {
  const token = localStorage.getItem("TOKENS");
  if (token && token != "undefined") {
    return;
  }
  const code = getQueryVariable("code");
  if (code) {
    alert(code);
    
    //获取access_token
    
    doFetch({
      url: "http://www.youtianchen.cn/web/authtoken",
      params: {
        code,
      },
    }).then((res) => {
      console.log('====================================');
      console.log(res);
      console.log('====================================');
      
    });
  } else {
    let uri = "http://www.youtianchen.cn"; //'http://www.sanbaodagong.com/wechat/index.html';
    window.location.href =
      "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx289794cd442ff592&redirect_uri=" +
      uri +
      "&response_type=code&scope=snsapi_base#wechat_redirect";
  }
}

4.2 前端拿到code传给后端,后端获取access_token(这个可以做各系统的绑定)

后端这里给出egg.js写出的代码:

// 判断token值从哪里获取
  async fetchAccessToken(code) {
    const { app } = this;
    const access_token = await app.redis.get('access_token');
    console.log(access_token, 'access_token');

    // redis 存在access_token
    if (!access_token) {
      const token = await this.fetchToken(code);
      return token;
    }
    // redis不存在access_token
    const istoken = await this.istoken(access_token);
    if (istoken) {
      return access_token;
    }
    const token = await this.fetchToken(code);
    return token;
  }

  // 判断token是否失效
  async istoken(token) {
    const { ctx, app } = this;
    const openid = await app.redis.get('openid');
    const res = await ctx.curl(
      `https://api.weixin.qq.com/sns/auth?access_token=${token}&openid=${openid}`,
      {
        // 必须指定 method
        method: 'GET',
        dataType: 'json',
      }
    );
    console.log(res, 'istoken');
    return res?.data?.errcode === 0;
  }

  // 获取token 定时任务
  async fetchToken(code) {
    const { ctx, app } = this;
    const appid = app.config.wechat_config.appid;
    const appsecret = app.config.wechat_config.appsecret;
    const refresh_token = await app.redis.get('refresh_token');
    const URL = code
      ? `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appid}&secret=${appsecret}&code=${code}&grant_type=authorization_code`
      : `https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=${appid}&grant_type=refresh_token&refresh_token=${refresh_token}`;
    const res = await ctx.curl(URL, {
      method: 'GET',
      dataType: 'json',
    });
    console.log(res, 'token_response');
    if (res.data.refresh_token) {
      await app.redis.set('refresh_token', res.data.refresh_token);
    }
    if (res.data.openid) {
      await app.redis.set('openid', res.data.openid);
    }
    if (res.data.access_token) {
      await app.redis.set('access_token', res.data.access_token);
      await this.createMenu(res.data.access_token);
      return res.data.access_token;
    }

    return null;
  }

4.3 后端拿到access_token可以生成签名
后端这里给出egg.js写出的代码:

// 判断ticket值从哪里获取
  async getAccessTicket() {
    const { app } = this;
    const ticket = await app.redis.get('ticket');
    // redis 存在ticket
    console.log(ticket, 'ticket');

    if (!ticket) {
      const res = await this.getTicket();
      return res;
    }
    // redis 存在ticket
    return ticket;
  }

  // 获取ticket 定时任务
  async getTicket() {
    const { ctx, app } = this;
    const access_token = await this.fetchAccessToken();
    console.log(access_token, '换key');
    const res = await ctx.curl(
      `https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${access_token}&type=jsapi`,
      {
        // 必须指定 method
        method: 'GET',
        dataType: 'json',
      }
    );
    console.log(res, 'ticket_response');
    if (res.data.ticket) {
      await app.redis.set('ticket', res.data.ticket);
      return res.data.ticket;
    }
    return null;
  }
  1. JS-SDK
yarn add weixin-js-sdk

5.1 公众号设置-功能设置
5.1.1 js接口安全域名配置
代码所在的服务器配置访问页面的url,例如:
访问页面地址如下:
http://gzh-test.nangaoyun.com/quality/#/welcome

那 js接口安全域名配置:http://gzh-test.nangaoyun.com/quality
需要把MP_verify_dPqSolp0G3VuCs9n.txt放在服务器http://gzh-test.nangaoyun.com/quality指向的文件夹下

访问页面地址如下:
http://gzh-test.nangaoyun.com/plan/#/welcome

那 js接口安全域名配置:http://gzh-test.nangaoyun.com/plan
需要把MP_verify_dPqSolp0G3VuCs9n.txt放在服务器http://gzh-test.nangaoyun.com/plan指向的文件夹下

以上我们看到访问地址在服务器的配置在同一个根目录下
因此可以只配置一个js接口安全域名:http://gzh-test.nangaoyun.com
需要把MP_verify_dPqSolp0G3VuCs9n.txt放在服务器http://gzh-test.nangaoyun.com/quality指向的文件夹下
//和http://gzh-test.nangaoyun.com/plan指向的文件夹下共同的根目录下面即可;

例如目录结构是这样的:
在这里插入图片描述

5.2 调用微信的一些功能,以下以扫码为例(前端代码)

//写一个公共方法:wxConfig

import { doFetch } from "./doFetch";
import { Toast } from "antd-mobile";
import wx from 'weixin-js-sdk';
export default async function (url) {
    let res = await doFetch({ url: '/pengli-wx/equip/common/jsSdk', params: { locUrl: url } });
    if (res?.code === 1) {
        let wxconfig = res?.jsSdk ?? {}
        wx.config({
            debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
            appId: wxconfig?.appId, // 必填,公众号的唯一标识
            timestamp: wxconfig?.timeStamp, // 必填,生成签名的时间戳
            nonceStr: wxconfig?.nonceStr, // 必填,生成签名的随机串
            signature: wxconfig?.signature,// 必填,签名
            jsApiList: [
                'scanQRCode'
            ] // 必填,需要使用的JS接口列表
        });
        wx.ready(function () {
            Toast.show({
                icon: 'success',
                content: '成功',
            })
        });

        wx.error(function (res) {
            Toast.show({
                icon: 'error',
                content: res.errMsg,
            })
        });
    }
}

按钮点击扫码:

async() => {
            await wxConfig(document.URL)
            wx.scanQRCode({
                needResult: 0, // 默认为0,扫描结果由微信处理,1则直接返回扫描结果,
                scanType: ["qrCode", "barCode"], // 可以指定扫二维码还是一维码,默认二者都有
                success: function (res) {
                    var result = res.resultStr; // 当needResult 为 1 时,扫码返回的结果
                }
            });
        }

**

PS: access_token和签名都是2小时过期

**
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1185973.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

杂货铺 | citespace的使用

安装教程 【CiteSpace保姆级教程1】文献综述怎么写&#xff1f; &#x1f4da;数据下载 1. 新建文件夹 2. 数据下载 知网高级检索 数据选中导出 &#xff1a;一次500 导出后重命名为download_xxx.txt&#xff0c;放到input文件里 3. 数据转换 把output里的数据复制到data里…

【算法与数据结构】17、LeetCode电话号码的字母组合

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;本题需要解决的问题有三个&#xff1a; 一、如何实现数字到字母的映射二、如何实现组合问题三、如何解…

移远EC600U-CN开发板 day03

控件探索-按钮&#xff08;lv.btn&#xff09; (1) 创建并显示一个按钮 * 核心代码 btn lv.btn(scr) #将按钮与src对象关联 btn.align(lv.ALIGN.CENTER,0,0) #居中显示&#xff08;第1个0表示x的偏移量&#xff0c;第2个0表示相对于y的偏移量&#xff09; label lv.l…

万字长文 - Python 日志记录器logging 百科全书 之 基础配置

万字长文 - Python 日志记录器logging 百科全书 之 基础配置 前言 在日常的开发中工作中&#xff0c;日志记录扮演着不可或缺的角色。它不仅能让我们了解应用程序的运行状况&#xff0c;还能帮助我们定位并解决各种问题。 最基本的&#xff0c;它记录了应用程序的运行情况&am…

说话人识别声纹识别CAM++,ECAPA-TDNN等算法

参考:https://www.modelscope.cn/models?page=1&tasks=speaker-verification&type=audio https://github.com/alibaba-damo-academy/3D-Speaker/blob/main/requirements.txt 单个声纹比较可以直接modelscope包运行 from modelscope.pipelines import pipeline sv_pi…

阿里云2023年双十一低至87/年

阿里云ECS11月销量王 99元/年 活动时间 2023年10月31日0点0分0秒至2026年3月31日23点59分59秒&#xff1b; 点击活动场地&#xff1a; 活动对象 满足以下全部条件的阿里云用户&#xff1a; 1、阿里云注册会员用户&#xff1b; 2、完成阿里云企业认证或个人认证用户&#xff1b…

学习Nginx配置

1.下载地址 官网地址&#xff1a;NGINX - 免费试用、软件下载、产品定价 (nginx-cn.net) 我这边选择NGINX 开源版 nginx: download 2.nginx的基本配置 配置文件语法 配置文件组成&#xff1a;注释行&#xff0c;指令块配置项和一系列指令配置项组成。 单个指令组成&#x…

自动控制原理--面试问答题

以下文中的&#xff0c;例如 s_1 为 s下角标1。面试加油&#xff01; 控制系统的三要素&#xff1a;稳准快。稳&#xff0c;系统最后不能震荡、发散&#xff0c;一定要收敛于某一个值&#xff1b;快&#xff0c;能够迅速达到系统的预设值&#xff1b;准&#xff0c;最后稳态值…

【MATLAB源码-第71期】基于matlab的萤火虫算法(FA)的无人机三维地图路径规划,输出最短路径和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 萤火虫算法&#xff08;Firefly Algorithm&#xff0c;FA&#xff09;是由剑桥大学的Xin-She Yang在2008年提出的一种元启发式优化算法。该算法的灵感来源于萤火虫闪烁的行为特征&#xff0c;主要用于解决连续的优化问题。萤…

线性代数(二)| 行列式性质 求值 特殊行列式 加边法 归纳法等多种方法

文章目录 1. 性质1.1 重要性质梳理1.1.1 转置和初等变换1.1.2加法行列式可拆分1.1.3 乘积行列式可拆分 1.2 行列式性质的应用1.2.1 简化运算1.2.2 将行列式转换为&#xff08;二&#xff09;中的特殊行列式 2 特殊行列式2.1 上三角或下三角行列式2.2 三叉行列式2.3 行列式行和&…

TensorFlow(1):深度学习的介绍

1 深度学习与机器学习的区别 学习目标&#xff1a;知道深度学习与机器学习的区别 区别&#xff1a;深度学习没有特征提取 1.1 特征提取方面 机器学习的特征工程步骤是要靠手动完成的&#xff0c;而且需要大量领域专业知识深度学习通常由多个层组成&#xff0c;它们通常将更简…

配置简单VLAN

1、 需求 &#xff1a; 1&#xff09;创建VLAN 10、20、30 2&#xff09;将端口加入VLAN 3&#xff09;查看VLAN信息 2、方案 使用eNSP搭建实验环境&#xff0c;如图所示。 3、步骤 实现此案例需要按照如下步骤进行。 1&#xff09;交换机创建VLAN 10、20、30 [sw1]vla…

云架构师学习------腾讯云通识-存储与数据库

云架构师学习------腾讯云通识-存储与数据库 云架构师学习------腾讯云通识-存储与数据库存储基础存储服务对象存储-COS产品概述功能概览产品优势 云硬盘-CBS产品概述产品功能产品优势云硬盘类型 文件存储-CFS产品概述产品功能产品优势文件存储类型及性能规格存储类型性能与规格…

《LeetCode力扣练习》代码随想录——数组(长度最小的子数组---Java)

《LeetCode力扣练习》代码随想录——数组&#xff08;长度最小的子数组—Java&#xff09; 刷题思路来源于 代码随想录 209. 长度最小的子数组 滑动窗口——O(n) class Solution {public int minSubArrayLen(int target, int[] nums) {if(nums.length1){return nums[0]>targ…

“2024杭州国际物联网展览会”定于4月份在杭州国际博览中心召开

随着科技的飞速发展&#xff0c;物联网已经成为当今社会的一个重要组成部分。物联网技术正在逐渐渗透到各个领域&#xff0c;为人们的生活带来更多的便利和智慧。物联网的发展趋势将受到技术、应用、安全等多方面的影响和推动。未来&#xff0c;物联网将更加智能化、自主化和安…

10个手机通讯录恢复软件,请收好以备不时之需!

随着我们的生活变得越来越数字化&#xff0c;我们中的许多人严重依赖智能手机和其他设备也就不足为奇了。我们在其中存储了大量有价值的信息&#xff0c;包括我们的联系人、笔记、消息等等。然而&#xff0c;这意味着当我们无法使用手机时&#xff0c;这可能是一个大问题。无法…

【FI】FB02中Coding Block字段如何设置为可修改

本文基于S/4 HANA 2022 关于FB02下会计凭证行上的可更改字段的控制&#xff0c;以前以为只受“凭证明细行更变规则”&#xff08;OB32&#xff09;的影响。 今天碰到了Coding Block字段的情况&#xff0c;它不受OB32的影响&#xff0c;而是受表TCOBX控制。 如何确认该字段是Cod…

论文阅读——Detection Hub(cvpr2023)

Detection Hub: Unifying Object Detection Datasets via Query Adaptation on Language Embedding 一、要解决的问题 大规模数据集可以提高模型性能&#xff0c;但是当训练多类别单一模型时&#xff0c;大规模数据集不能用在目标检测任务上&#xff0c;因为两个困难&#xff1…

windows内存取证-简单

使用工具&#xff1a; volatility3-develop 题干&#xff1a; 作为 Security Blue 团队的成员&#xff0c;您的任务是使用 Redline 和 Volatility 工具分析内存转储。您的目标是跟踪攻击者在受感染计算机上采取的步骤&#xff0c;并确定他们如何设法绕过网络入侵检测系统“N…

设计模式—结构型模式之装饰器模式

设计模式—结构型模式之装饰器模式 适配器是连接两个类&#xff0c;可以增强一个类&#xff0c;装饰器是增强一个类。 向一个现有的对象添加新的功能&#xff0c;同时又不改变其结构。属于对象结构型模式。 创建了一个装饰类&#xff0c;用来包装原有的类&#xff0c;并在保…