微信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的保护。

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

相关推荐
一 乐37 分钟前
婚纱摄影网站|基于ssm + vue婚纱摄影网站系统(源码+数据库+文档)
前端·javascript·数据库·vue.js·spring boot·后端
C_心欲无痕1 小时前
ts - tsconfig.json配置讲解
linux·前端·ubuntu·typescript·json
清沫1 小时前
Claude Skills:Agent 能力扩展的新范式
前端·ai编程
yinuo2 小时前
前端跨页面通信终极指南:方案拆解、对比分析
前端
yinuo2 小时前
前端跨页面通讯终极指南⑨:IndexedDB 用法全解析
前端
xkxnq3 小时前
第二阶段:Vue 组件化开发(第 16天)
前端·javascript·vue.js
烛阴3 小时前
拒绝配置地狱!5 分钟搭建 Three.js + Parcel 完美开发环境
前端·webgl·three.js
xkxnq3 小时前
第一阶段:Vue 基础入门(第 15天)
前端·javascript·vue.js
anyup4 小时前
2026第一站:分享我在高德大赛现场学到的技术、产品与心得
前端·架构·harmonyos
BBBBBAAAAAi5 小时前
Claude Code安装记录
开发语言·前端·javascript