微信服务号接入网页-获取用户授权,定位权限

1,098 阅读2分钟

1.准备工作

  • 申请公众号或者企业号。
  • 域名备案--公众号链接网页必须使用域名且不能有端口号。

以上两项工作必须前置去做,需要一定的时间周期

2.开发工作

开发前置准备

  1. 申请一个测试号。
  2. 下载微信开发者工具。
  3. 注册内网映射工具natapp并购买免费隧道。注意免费隧道每次启动域名会变更。

配置测试号

  • js接口安全域名填写,测试号可以填写ip:端口号,注意此处是域名,不是链接,不能有http或者https image.png

  • 找到网页账号-网页授权获取用户基本信息,编辑填写用来获取用户信息的网页域名。

image.png

image.png

登录授权校验

在页面入口添加以下处理函数. 其中:appID,appsecret来自你自己的公众号或者测试号 getWechatAuthCode会在进入网页时要求用户授权用户信息。之后携带code跳转到当前网页。 getUserInfoFromCode 则通过url得中的code,调用服务端接口获取用户信息。

// 获取微信授权码
const getWechatAuthCode = () => {
  const appId = appid;
  const redirectUri = encodeURIComponent(window.location.href);
  const scope = 'snsapi_userinfo';
  const state = 'STATE';
  const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirectUri}&response_type=code&scope=${scope}&state=${state}#wechat_redirect`;
  window.location.href = url;
};

// 获取用户信息
const getUserInfoFromCode = async (code: string) => {
  try {
    const userInfoResponse = await axios.get(`/meteo-server/v1/wx/user-info?appid=${appid}&secret=${secret}&code=${code}&grant_type=authorization_code`);
    userInfo.value = userInfoResponse.data;
    console.log('微信用户信息', userInfoResponse.data.data);
    localStorage.setItem('userInfo', JSON.stringify(userInfoResponse.data.data));
  } catch (error) {
    userInfo.value = null;
    localStorage.removeItem('userInfo');
    console.error('获取微信用户信息失败', error);
  }
};

服务端解析code获取用户信息代码如下: 注意网页授权链接和服务端授权链接不同。 获取用户信息分为两步:

  1. 通过code获取access_token和openid。如果不需要用户信息,到这一步即可。
  2. 通过access_token获取用户信息
app.get('/winxin/get/userinfo', async (req, res) => {
  try {
    const { appid, secret, code, grant_type } = req.query;
    // 获取access_token
    const url = `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appid}&secret=${secret}&code=${code}&grant_type=${grant_type}`;

    const tokenRes = await axios.get(url);
    if(tokenRes.data) {
      const { access_token, openid } = tokenRes.data;
      const url = `https://api.weixin.qq.com/sns/userinfo?access_token=${access_token}&openid=${openid}&lang=zh_CN`;
      const response = await axios.get(url);
      res.json(response.data);
    }
  } catch (error) {
    console.error('请求微信 API 失败', error);
    res.status(500).send({ error: 'Internal Server Error' });
  }
});

获取用户定位

调用微信得js-sdk来获取用户信息

// 配置并初始化sdk
const getWxConfig = async () => {
  try {
    const curUrl = encodeURIComponent(window.location.href);
    // 后端接口获取 signature, nonceStr, timestamp  
    const response = await axios.get('/v1/wx/api-sig?api=' + curUrl); 
    const { timestamp, nonceStr, signature, appid } = response.data.data;
    wx.config({
      debug: false, // 开启调试模式
      appId: appid,
      timestamp: timestamp + "",
      nonceStr,
      signature,
      jsApiList: ['getLocation'] // 需要使用的微信 API 列表
    });

    wx.ready(() => {
      console.log('微信 JS-SDK 初始化成功');
      getUserLocation();
    });

    wx.error((res: any) => {
      console.error('微信 JS-SDK 初始化失败', res);
    });
  } catch (error) {
    console.error('获取微信 JS-SDK 配置参数失败', error);
  }
};

// 获取用户位置
const getUserLocation = () => {
  wx.getLocation({
    type: 'wgs84', // 默认为 wgs84 的地理坐标系统
    success: (res: any) => {
      userLocation.value = {
        latitude: res.latitude,
        longitude: res.longitude,
        speed: res.speed,
        accuracy: res.accuracy
      };
      // 做其它处理
      // ...
      // 清除错误提示
      locationError.value = ''; 
    },
    fail: (err: any) => {
      console.error('获取用户位置失败', err);
      if (err.errMsg.includes('auth deny')) {
        locationError.value = '您已拒绝授权位置权限,请在微信设置中开启位置权限。';
      } else {
        locationError.value = '获取位置失败,请检查您的网络连接。';
      }
    }
  });
};

踩坑记录

1. redirect_uri错误

原因:网页授权获取用户基本信息里面填写域名和调试域名不同或者带了http

2. 获取用户信息40001

原因:acces_token 不能返回给客户端,否则会直接失效。 前端直接通过code获取access_token会跨域,自己搭建服务端,写了两个api,一个获取并返回access_token,另一个解析access_token获取用户信息,始终提示access_token不合法。直接在服务端处理完成返回用户信息,可验证通过。

其他:网页授权对应获取access_token以及获取用户信息的api不同,必须是互相配套的接口,否则也会出现40001不合法的情况。

3. sdk初始化报错url domain错误;signature校验错误。

    1. signature校验错误 原因:需要传给服务端当前页面#以前全部信息,包括query信息,不然会导致signature错误
    1. url domain错误 原因:js接口安全域名和当前调试用的url域名不一致。

4. 上线出现sdk初始化错误

请检查公众号配置白名单。

5. 菜单进入单页面,出现返回工具条处理方案

在服务号菜单配置网页链接时,不要直接使用系统网页地址,可以直接使用微信获取code校验码的链接: open.weixin.qq.com/connect/oau… 其中redirect_uri为H5页面链接地址,各个参数根据你的公众号设置对应即可。

6. 定位信息返回地图初始化异常--微信sdk在不同系统环境下返回参数类型可能不一致

注意:开发者工具以及苹果手机获取的地址经纬度为数值。安卓手机获取的地址经纬度为字符串。虽然官网给的文档说明是数值型。如果出现使用定位经纬度在不同手机系统遇到问题,可从这个角度排查sdk返回的数据以及类型是否一致。