在网站上实现 微信扫码登录,需要结合 微信公众号网页授权机制 和 后端服务 完成。以下是详细步骤和代码示例:
1. 整体流程
用户点击“微信登录”按钮 → 网站生成一个 带唯一标识的二维码(如 参数)。用户用微信扫码 → 微信公众号跳转到授权页面(需用户确认登录)。微信服务器回调你的后端接口 → 后端获取
state 和
code。后端用
state 换取
code 和
openid → 绑定用户信息到网站账号。网站跳转回登录成功页面 → 完成登录。
session_key
2. 准备工作
(1) 公众号配置
确保公众号是 已认证的服务号(订阅号不支持网页授权)。在 公众号后台 → 设置与开发 → 接口权限 → 网页服务 → 网页授权:
设置 授权回调域名(如 ,不能带
yourdomain.com 或端口)。确保已开通
http:// 权限(用于扫码登录)。
snsapi_login
(2) 后端准备
需要一个后端服务(如 Java/Python/Node.js)处理微信回调。准备以下微信 API 地址:
生成授权 URL:
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect
用 换取
code:
openid
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=APPSECRET&code=CODE&grant_type=authorization_code
3. 详细实现步骤
(1) 前端:生成微信扫码按钮
在网站登录页面添加一个按钮,点击后跳转到微信授权 URL:
<button id="wechat-login-btn">微信扫码登录</button>
<script>
document.getElementById('wechat-login-btn').onclick = function() {
// 生成一个唯一 state(防止 CSRF 攻击)
const state = Math.random().toString(36).substr(2, 10);
// 存储 state 到 sessionStorage(后续校验用)
sessionStorage.setItem('wechat_login_state', state);
// 跳转到微信授权页面
const redirectUri = encodeURIComponent('https://yourdomain.com/api/wechat/callback');
const appid = '你的公众号APPID';
window.location.href = `https://open.weixin.qq.com/connect/qrconnect?appid=${appid}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_login&state=${state}#wechat_redirect`;
};
</script>
(2) 后端:处理微信回调
当用户扫码确认登录后,微信会重定向到你的 ,并带上
redirect_uri 和
code。
state
示例(Node.js Express):
const express = require('express');
const axios = require('axios');
const app = express();
// 微信回调接口
app.get('/api/wechat/callback', async (req, res) => {
const { code, state } = req.query;
// 校验 state(防止 CSRF)
const expectedState = sessionStorage.getItem('wechat_login_state'); // 实际应从前端存储中获取(此处简化)
if (state !== expectedState) {
return res.send('状态不匹配,请重试');
}
try {
// 用 code 换取 openid 和 session_key
const appid = '你的公众号APPID';
const appsecret = '你的公众号APPSECRET';
const url = `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appid}&secret=${appsecret}&code=${code}&grant_type=authorization_code`;
const response = await axios.get(url);
const { openid, unionid } = response.data; // unionid 可能为空(需公众号关联开放平台)
// TODO: 根据 openid 查询或创建网站用户
// 例如:检查数据库是否存在该 openid,若不存在则创建新用户
// 生成网站登录态(如 JWT 或 Session)
const token = generateWebsiteToken(openid); // 自定义函数
// 跳转回登录成功页面,并带上 token
res.redirect(`https://yourdomain.com/login-success?token=${token}`);
} catch (error) {
console.error('微信登录失败:', error);
res.send('微信登录失败,请重试');
}
});
app.listen(3000, () => console.log('Server running on port 3000'));
(3) 前端:处理登录成功跳转
在 页面解析
login-success 并完成登录:
token
// login-success.html
<script>
const urlParams = new URLSearchParams(window.location.search);
const token = urlParams.get('token');
if (token) {
// 存储 token 到 localStorage 或 Cookie
localStorage.setItem('website_token', token);
// 跳转到首页或用户中心
window.location.href = '/';
} else {
alert('登录失败');
}
</script>
4. 关键注意事项
(1) 安全性
state 校验:必须校验 防止 CSRF 攻击。HTTPS:微信要求回调域名必须使用 HTTPS。APPSECRET 保护:不要将
state 暴露在前端代码中。
APPSECRET
(2) 用户体验优化
轮询检查登录状态:前端可以轮询检查用户是否扫码成功(需后端支持)。二维码过期处理:微信二维码默认 5 分钟过期,需提示用户刷新。
(3) 用户绑定
如果用户是首次使用微信登录,需绑定手机号或邮箱(根据业务需求)。示例流程:
微信登录后跳转到绑定页面。用户输入手机号/验证码完成绑定。
(4) 错误处理
常见错误码:
:
40029 无效或已使用。
code:
40163 或
appid 错误。参考 微信官方文档。
redirect_uri
5. 完整代码示例(简化版)
前端(HTML + JavaScript)
<!DOCTYPE html>
<html>
<head>
<title>微信扫码登录</title>
</head>
<body>
<button id="wechat-login-btn">微信扫码登录</button>
<script>
document.getElementById('wechat-login-btn').onclick = function() {
const state = 'random_state_' + Math.random().toString(36).substr(2, 8);
sessionStorage.setItem('wechat_login_state', state);
const redirectUri = encodeURIComponent('https://yourdomain.com/api/wechat/callback');
const appid = '你的APPID';
window.location.href = `https://open.weixin.qq.com/connect/qrconnect?appid=${appid}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_login&state=${state}#wechat_redirect`;
};
</script>
</body>
</html>
后端(Node.js)
const express = require('express');
const axios = require('axios');
const app = express();
app.get('/api/wechat/callback', async (req, res) => {
const { code, state } = req.query;
const expectedState = sessionStorage.getItem('wechat_login_state'); // 实际应从数据库或 Redis 获取
if (state !== expectedState) {
return res.send('状态不匹配');
}
try {
const response = await axios.get(
`https://api.weixin.qq.com/sns/oauth2/access_token?appid=你的APPID&secret=你的APPSECRET&code=${code}&grant_type=authorization_code`
);
const { openid } = response.data;
// 模拟生成网站 token
const token = 'website_token_' + Math.random().toString(36).substr(2, 16);
res.redirect(`https://yourdomain.com/login-success?token=${token}`);
} catch (error) {
res.send('微信登录失败');
}
});
app.listen(3000, () => console.log('Server running'));
6. 总结
| 步骤 | 关键点 |
|---|---|
| 1. 公众号配置 | 认证服务号 + 设置授权回调域名 |
| 2. 前端生成授权 URL | 包含 、、 |
| 3. 后端处理回调 | 用 换取 + 校验 |
| 4. 用户绑定 | 首次登录需绑定账号 |
| 5. 跳转成功页面 | 返回网站 token 完成登录 |
推荐实践:
使用 JWT 或 Session 管理登录态。将 存储在 Redis 中(避免前端存储不安全)。参考微信官方文档:网页授权获取用户基本信息。
state

















暂无评论内容