微信H5登录怎么实现?uniapp+node.js一篇搞定! 附完整代码

大家好,我是一诺。今天我们来聊聊如何在微信公众号H5开发中实现网页授权登录。

这篇文中 以uniapp和node.js为例,来实现微信H5授权登录,并且会补充一些细节和优化建议,帮助大家更好地理解和应用。

一、为什么需要网页授权?

在微信公众号H5开发中,网页授权的主要目的是获取用户的基本信息,尤其是openid。这个openid是用户在公众号内的唯一标识,类似于用户的身份证号。

有了它,我们才能实现用户登录、支付等功能。因此,掌握网页授权的实现方法,对于开发功能完善的微信公众号H5应用至关重要。

微信授权流程

图片来源网络

二、静默授权 vs 非静默授权

在开始动手之前,我们需要先了解微信网页授权的两种方式:静默授权非静默授权

1. 静默授权(snsapi_base)

静默授权是一种用户无感知的授权方式,不会弹出授权页面。它的主要作用是获取用户的openid,适用于不需要用户额外信息的场景,比如自动登录。缺点是它无法获取用户的头像、昵称等详细信息。

2. 非静默授权(snsapi_userinfo)

非静默授权会弹出一个授权页面,用户需要手动同意授权。这种方式不仅可以获取openid,还能获取用户的昵称、性别、所在地等基本信息。即使公众号没有被用户关注,只要用户授权,我们也能拿到这些信息。

null

三、使用uniapp实现网页授权(H5)

1. 开发配置

在开始编码之前,我们需要在微信公众平台进行一些配置。具体步骤如下:

  1. 配置授权回调域名:登录微信公众平台,进入"开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息",在这里设置授权回调域名。这个域名是微信授权后跳转的地址,必须正确配置,否则授权会失败。
  2. 使用微信测试号 :如果你还没有认证的公众号,可以使用微信测试号进行开发。测试号支持调用所有的微信API,非常适合开发和调试。你可以在这里申请测试号:微信公众平台测试号
null
  1. 配置OAuth2.0:在微信测试号中,找到接口权限列表,修改网页授权地址。联调时可以使用本地IP。
null
  1. 修改JS安全域名:确保你的JS安全域名已经正确配置,否则无法调用微信的JS接口。
null

2. 提前准备工作

在代码中,我们需要定义几个关键参数:

  • appid:公众号的唯一标识,用于区分不同的公众号。
  • redirect_uri:授权后重定向的回调链接地址,即获取用户信息后跳转的目标页面。
  • scope :授权方式,可选值为snsapi_userinfo(非静默授权)或snsapi_base(静默授权)。
ini 复制代码
const appid = "xxxxxxxxxxx"; // 公众号的唯一标识
const redirect_uri = "http://xxx.xxxx.xxx"; // 授权后重定向的回调链接地址
const scope = "snsapi_userinfo"; // 非静默授权:snsapi_userinfo  静默授权:snsapi_base

3. 授权过程

授权操作通常在uniapp的onLaunch生命周期函数中进行,分为以下几个步骤:

1. 获取code

如果本地存储中没有openid,则需要获取code。通过拼接微信授权链接,引导用户进行授权操作。

javascript 复制代码
onLaunch(e) {
    const openid = uni.getStorageSync('OPENID');
    // 不存在openid时获取code
    if (!openid) {
        // 获取code
        document.location.replace(`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=${scope}&state=STATE#wechat_redirect`);
    }
}

2. 通过code换取用户信息

获取code后,微信会跳转到redirect_uri/?code=CODE&state=STATE。此时我们可以从URL中获取code参数,并调用后端的getWxAuthorize接口获取用户信息,最后将openid存储到本地。

javascript 复制代码
async onLaunch(e) {
    const openid = uni.getStorageSync('OPENID');
    if ((e && e.query && e.query.code) && !openid) {
        // 请求后端接口获取用户信息
        let result = await getWxAuthorize({ code: e.query.code, scope: "snsapi_userinfo" });
        // 保存用户的openid
        uni.setStorageSync('OPENID', result.data.openid);
    }
}

注意 :公众号的secret和获取到的access_token安全级别非常高,必须仅保存在服务器端,严禁传递给客户端。

4. 使用node.js获取用户信息接口

这部分主要是后端逻辑,涉及到与微信服务器的交互。我们需要使用appidappsecret来获取用户信息。

ini 复制代码
const axios = require("axios");
const appid = "xxxxxxxxxxx"; // 公众号的唯一标识
const secret = "xxxxxxxxxxx"; // 公众号的appsecret

function setAuthorize(params) {
    return new Promise(async (resolve) => {
        let userinfo = {};
        // 通过code换取网页授权access_token
        let result = await axios(`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appid}&secret=${secret}&code=${params.code}&grant_type=authorization_code`);
        result = result.data;
        console.log("access_token结果", result);
        if (result.errcode) resolve({ code: 403, msg: '' });
        userinfo.openid = result.openid;
        // scope=snsapi_userinfo弹出网页授权
        if (params.scope == 'snsapi_userinfo') {
            // 获取用户信息
            let info = await axios(`https://api.weixin.qq.com/sns/userinfo?access_token=${result.access_token}&openid=${result.openid}&lang=zh_CN`);
            info = info.data;
            console.log("用户信息", info);
            if (info.errcode) resolve({ code: 403, msg: '' });
            userinfo = info;
        }
        // 对数据库进行新增用户或者更新用户信息操作
        resolve({ code: 0, msg: '', data: userinfo });
    });
}

5. 完整H5静默登录代码

综合上述步骤,最终的uniapp代码如下:

javascript 复制代码
import { getWxAuthorize } from "@/api/wx.js";

export default {
    async onLaunch(e) {
        const openid = uni.getStorageSync('OPENID');
        const code = uni.getStorageSync('CODE');
        if (!code && !(e && e.query && e.query.code) && !openid) {
            // 不存在存储的code、地址参数code和openid
            // 存储当前初始页面历史列表数量
            uni.setStorageSync("historyLength", history.length);
            // 获取code
            document.location.replace(`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${redirect_uri}&response_type=code&scope=${scope}&state=STATE#wechat_redirect`);
        } else if ((e && e.query && e.query.code) && !openid) {
            // 存在地址参数code,但不存在openid
            uni.setStorageSync('CODE', e.query.code);
            const historyLength = uni.getStorageSync("historyLength");
            // 跳转回初始页面
            history.go(-(history.length - historyLength));
        } else if (code && !openid) {
            // 存在存储的code,但不存在openid
            uni.removeStorageSync('CODE');
            // 请求后端接口获取用户信息
            let result = await getWxAuthorize({ code, scope: "snsapi_userinfo" });
            // 保存用户的openid
            uni.setStorageSync('OPENID', result.data.openid);
        }
    }
}

四、联调测试

为了确保我们的代码能够正常工作,我们需要使用微信开发者工具进行联调测试。你可以在这里下载微信开发者工具:微信开发者工具下载

  1. 登录微信开发者工具:使用你绑定公众号的微信登录,否则无法进行联调。
  2. 输入URL地址 :在顶部工具栏输入你的H5页面地址,然后查看控制台打印的信息,确保已经获取到用户的openid
null

五、常见问题与解决方案

1. 登录授权后跳转空白页面

问题描述:微信授权后回调页面返回时可能会跳转到空白页。

解决方案

  • 在初次授权时,存储页面历史列表的长度。
  • code回调页面之后,通过history.go方法返回到初始页面。
go 复制代码
// 第一次进入页面
uni.setStorageSync("historyLength", history.length);

// 在code回调页面之后
const historyLength = uni.getStorageSync("historyLength");
history.go(-(history.length - historyLength));

2. 当前页面的URL未注册

问题描述:在微信公众号H5调起支付时,点击支付按钮出现"当前页面的URL未注册"的提示。

解决方案

  • 登录微信商户平台,进入"产品中心 - 开发配置",配置支付授权路径。确保你调起支付的页面URL已经正确配置。
null

六、总结

通过本文的详细介绍,相信大家对微信H5授权登录的实现有了更清晰的理解。无论是静默授权还是非静默授权,核心流程都是获取code,然后通过code换取用户信息。在实际开发中,务必注意安全性,尤其是appsecretaccess_token的保护。

如果你在开发过程中遇到任何问题,欢迎在评论区留言

相关推荐
崔庆才丨静觅9 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606110 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了10 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅10 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅11 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅11 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment11 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅11 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊11 小时前
jwt介绍
前端
爱敲代码的小鱼11 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax