wx.config的前后端实现express和react

wx.config 是微信JS-SDK的配置接口,用于初始化微信JS-SDK。为了确保安全性,微信要求每次调用JS-SDK时都需要进行签名认证。签名认证需要使用jsapi_ticket,而jsapi_ticket需要通过access_token获取。

以下是实现wx.config的步骤:

后端部分

  1. 获取Access Token
    你需要定期获取并缓存access_token,因为它的有效期是7200秒(2小时)。

  2. 获取JSAPI Ticket
    使用access_token获取jsapi_ticket,并缓存它,因为它的有效期也是7200秒。

  3. 生成签名
    根据jsapi_ticket、当前网页的URL、随机字符串(nonceStr)和时间戳(timestamp)生成签名。

  4. 提供签名接口
    提供一个后端接口,前端可以调用这个接口获取签名信息。

以下是一个示例实现:

import express from 'express';
import fetch from 'node-fetch';
import crypto from 'crypto';

const app = express();
app.use(express.json());

const appId = 'YOUR_APP_ID';
const appSecret = 'YOUR_APP_SECRET';

let accessToken = '';
let jsapiTicket = '';
let tokenExpiresAt = 0;
let ticketExpiresAt = 0;

// 获取Access Token
async function getAccessToken() {
  if (Date.now() < tokenExpiresAt) {
    return accessToken;
  }

  const response = await fetch(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appId}&secret=${appSecret}`);
  const data = await response.json();
  accessToken = data.access_token;
  tokenExpiresAt = Date.now() + (data.expires_in - 300) * 1000; // 提前5分钟过期

  return accessToken;
}

// 获取JSAPI Ticket
async function getJsapiTicket() {
  if (Date.now() < ticketExpiresAt) {
    return jsapiTicket;
  }

  const token = await getAccessToken();
  const response = await fetch(`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${token}&type=jsapi`);
  const data = await response.json();
  jsapiTicket = data.ticket;
  ticketExpiresAt = Date.now() + (data.expires_in - 300) * 1000; // 提前5分钟过期

  return jsapiTicket;
}

// 生成签名
function createSignature(ticket: string, nonceStr: string, timestamp: number, url: string) {
  const string1 = `jsapi_ticket=${ticket}&noncestr=${nonceStr}&timestamp=${timestamp}&url=${url}`;
  const hash = crypto.createHash('sha1');
  hash.update(string1);
  return hash.digest('hex');
}

// 提供签名接口
app.post('/api/getSignature', async (req, res) => {
  const { url } = req.body;

  try {
    const ticket = await getJsapiTicket();
    const nonceStr = Math.random().toString(36).substr(2, 15);
    const timestamp = Math.floor(Date.now() / 1000);
    const signature = createSignature(ticket, nonceStr, timestamp, url);

    res.json({
      appId,
      timestamp,
      nonceStr,
      signature,
    });
  } catch (error) {
    res.status(500).json({ error: 'Failed to get signature' });
  }
});

app.listen(3000, () => {
  console.log('Server is running on port 3000');
});

前端部分

前端需要调用后端的签名接口,并使用返回的数据配置wx.config

import React, { useEffect } from 'react';

const YourComponent = () => {
  useEffect(() => {
    const url = window.location.href.split('#')[0];

    fetch('/api/getSignature', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ url }),
    })
      .then(response => response.json())
      .then(data => {
        wx.config({
          debug: true, // 开启调试模式
          appId: data.appId,
          timestamp: data.timestamp,
          nonceStr: data.nonceStr,
          signature: data.signature,
          jsApiList: [
            // 需要使用的JS接口列表
            'onMenuShareTimeline',
            'onMenuShareAppMessage',
            // 其他接口
          ],
        });

        wx.ready(() => {
          // wx API 调用
        });

        wx.error((res) => {
          console.error('wx.config 错误:', res);
        });
      })
      .catch(error => {
        console.error('Error:', error);
      });
  }, []);

  return <div>Your Component</div>;
};

export default YourComponent;

总结

  1. 后端定期获取并缓存access_tokenjsapi_ticket
  2. 后端提供一个签名接口,生成并返回签名信息。
  3. 前端调用后端签名接口,并使用返回的数据配置wx.config

请确保在微信公众平台上正确配置了JS接口安全域名。

posted @ 2024-07-05 22:35  让速不让路  阅读(8)  评论(0编辑  收藏  举报