大家好,我是一诺。今天我们来聊聊如何在微信公众号H5开发中实现网页授权登录。
这篇文中 以uniapp和node.js为例,来实现微信H5授权登录,并且会补充一些细节和优化建议,帮助大家更好地理解和应用。
一、为什么需要网页授权?
在微信公众号H5开发中,网页授权的主要目的是获取用户的基本信息,尤其是openid。这个openid是用户在公众号内的唯一标识,类似于用户的身份证号。
有了它,我们才能实现用户登录、支付等功能。因此,掌握网页授权的实现方法,对于开发功能完善的微信公众号H5应用至关重要。
微信授权流程
图片来源网络
二、静默授权 vs 非静默授权
在开始动手之前,我们需要先了解微信网页授权的两种方式:静默授权 和非静默授权。
1. 静默授权(snsapi_base)
静默授权是一种用户无感知的授权方式,不会弹出授权页面。它的主要作用是获取用户的openid,适用于不需要用户额外信息的场景,比如自动登录。缺点是它无法获取用户的头像、昵称等详细信息。
2. 非静默授权(snsapi_userinfo)
非静默授权会弹出一个授权页面,用户需要手动同意授权。这种方式不仅可以获取openid,还能获取用户的昵称、性别、所在地等基本信息。即使公众号没有被用户关注,只要用户授权,我们也能拿到这些信息。
三、使用uniapp实现网页授权(H5)
1. 开发配置
在开始编码之前,我们需要在微信公众平台进行一些配置。具体步骤如下:
- 配置授权回调域名:登录微信公众平台,进入"开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息",在这里设置授权回调域名。这个域名是微信授权后跳转的地址,必须正确配置,否则授权会失败。
- 使用微信测试号 :如果你还没有认证的公众号,可以使用微信测试号进行开发。测试号支持调用所有的微信API,非常适合开发和调试。你可以在这里申请测试号:微信公众平台测试号。
- 配置OAuth2.0:在微信测试号中,找到接口权限列表,修改网页授权地址。联调时可以使用本地IP。
- 修改JS安全域名:确保你的JS安全域名已经正确配置,否则无法调用微信的JS接口。
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获取用户信息接口
这部分主要是后端逻辑,涉及到与微信服务器的交互。我们需要使用appid和appsecret来获取用户信息。
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);
}
}
}
四、联调测试
为了确保我们的代码能够正常工作,我们需要使用微信开发者工具进行联调测试。你可以在这里下载微信开发者工具:微信开发者工具下载。
- 登录微信开发者工具:使用你绑定公众号的微信登录,否则无法进行联调。
- 输入URL地址 :在顶部工具栏输入你的H5页面地址,然后查看控制台打印的信息,确保已经获取到用户的
openid。
五、常见问题与解决方案
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已经正确配置。
六、总结
通过本文的详细介绍,相信大家对微信H5授权登录的实现有了更清晰的理解。无论是静默授权还是非静默授权,核心流程都是获取code,然后通过code换取用户信息。在实际开发中,务必注意安全性,尤其是appsecret和access_token的保护。
如果你在开发过程中遇到任何问题,欢迎在评论区留言