关注微信公众号登录小程序
关注微信公众号登录小程序
通过 关注微信公众号实现登录,本质是利用微信的 OpenID/UnionID 机制 将公众号用户与小程序的账号体系打通。以下是具体实现步骤和代码示例:
一、整体流程
sequenceDiagram
participant 用户
participant 小程序
participant 公众号
participant 服务端
用户->>小程序: 点击「公众号登录」
小程序->>服务端: 生成临时二维码(带场景值scene_id)
服务端->>小程序: 返回二维码
用户->>公众号: 扫码关注(或已关注用户扫码)
公众号->>服务端: 推送扫码事件(带scene_id和用户OpenID)
服务端->>小程序: 通过WebSocket/轮询通知登录成功
小程序->>用户: 完成登录二、详细步骤
1. 准备工作
公众号要求:
必须是服务号(订阅号部分接口无权限)。
开通 网页授权 和 模板消息 权限(在微信公众平台配置)。
小程序要求:
与公众号在同一微信开放平台账号下绑定(获取UnionID必须)。
服务端:
准备存储用户关联关系(如
openid_mapping表)。
2. 生成带场景值的二维码
在小程序中生成临时二维码,关联当前登录会话:
// 小程序端:请求服务端生成二维码
wx.request({
url: 'https://your-server.com/api/generate-qrcode',
data: { session_id: '用户临时标识' },
success(res) {
// 显示二维码(res.data.qrcode_url)
}
});服务端示例(Node.js):
const qrcode = require('qrcode');
const { createTempQRCode } = require('微信公众平台API');
app.post('/api/generate-qrcode', async (req, res) => {
const scene_id = `login_${Date.now()}`; // 唯一场景值
const qrCodeUrl = await createTempQRCode(scene_id, 300); // 有效期300秒
// 存储scene_id与session_id的关联
cache.set(`scene:${scene_id}`, req.body.session_id);
res.json({ qrcode_url: qrCodeUrl });
});3. 用户扫码并关注公众号
用户扫描二维码后:
如果已关注公众号,微信会立即推送事件到你的服务器。
如果未关注,关注后才会推送。
公众号服务器配置(接收事件):
// 微信配置的公众号消息接口
router.post('/wechat/event', (req, res) => {
const { Event, EventKey, FromUserName } = req.body;
if (Event === 'SCAN' && EventKey.startsWith('login_')) {
const scene_id = EventKey;
const openid = FromUserName;
// 1. 获取用户UnionID(需网页授权)
// 2. 关联小程序账号
linkAccount(scene_id, openid);
}
res.send('success');
});4. 关联小程序账号
通过 UnionID 打通公众号和小程序用户:
async function linkAccount(scene_id, openid) {
// 1. 获取UnionID(需公众号网页授权)
const unionid = await getUnionID(openid);
// 2. 查询是否已绑定过小程序用户
const miniUser = db.query('SELECT * FROM users WHERE unionid = ?', [unionid]);
// 3. 通知小程序登录成功
const session_id = cache.get(`scene:${scene_id}`);
if (miniUser) {
ws.send(session_id, { action: 'login_success', user_id: miniUser.id });
} else {
// 新用户注册逻辑
ws.send(session_id, { action: 'register', unionid });
}
}5. 小程序完成登录
通过 WebSocket 或轮询接收登录状态:
// 小程序端:轮询检查登录状态
function checkLoginStatus(session_id) {
setInterval(() => {
wx.request({
url: 'https://your-server.com/api/check-login',
data: { session_id },
success(res) {
if (res.data.logged_in) {
clearInterval();
wx.setStorageSync('token', res.data.token);
}
}
});
}, 1000);
}三、关键API与配置
四、注意事项
用户未关注公众号:
需在二维码旁提示“扫码后关注公众号自动登录”。
安全性:
使用 HTTPS 传输数据。
二维码有效期建议 3-5 分钟。
UnionID 必须:
若公众号和小程序未绑定到同一开放平台,只能通过 OpenID 匹配(不推荐)。
用户体验:
提供备选登录方式(如手机号登录)。
扫码后可在公众号内发送登录成功提示。
五、优化方案
静默授权:通过公众号菜单提前获取用户授权,避免扫码后二次确认。
跨设备登录:若用户手机扫描PC端二维码,可通过公众号模板消息发送登录确认。
通过以上流程,即可实现“关注公众号即登录小程序”的无缝体验。