微信登录接入指南
微信开放平台的需要企业认证,个人开发者无法申请。
·
微信登录接入指南
⚠️ 重要提示:没有企业怎么办?
问题
微信开放平台的网站应用需要企业认证,个人开发者无法申请。
解决方案
方案一:暂时跳过微信登录(推荐)
- ✅ 先实现其他登录方式:手机号登录、QQ登录、微博登录
- ✅ 这些登录方式对个人开发者更友好
- ✅ 等有企业资质后再接入微信登录
- 💡 建议:先实现手机号登录,这是最通用的登录方式
方案二:使用微信公众平台(需要公众号)
- 注册并认证公众号(订阅号免费,服务号需认证)
- 使用网页授权获取用户信息
- ⚠️ 限制:需要用户关注公众号,体验不如开放平台
方案三:使用第三方登录服务
- 使用 Authing、Auth0 等第三方服务
- 优点:无需企业认证,快速接入
- 缺点:可能有费用,依赖第三方
方案四:使用测试环境(仅开发测试)
- 使用微信开放平台提供的测试账号
- ⚠️ 仅用于开发测试,不能用于生产环境
一、准备工作
1. 注册微信开放平台账号
- 访问:https://open.weixin.qq.com/
- 注册并完成企业认证(个人开发者无法创建网站应用)
- 认证费用:300元/年
- ⚠️ 如果没有企业,请参考上方的解决方案
2. 创建网站应用
- 登录微信开放平台
- 进入"管理中心" -> “网站应用” -> “创建网站应用”
- 填写应用信息:
- 应用名称
- 应用简介
- 应用官网
- 应用图标
- 获取关键信息:
- AppID(应用ID)
- AppSecret(应用密钥)
3. 配置授权回调域名
- 在应用详情页设置"授权回调域名"
- 例如:
yourdomain.com(不需要加协议和路径) - 注意:只能设置一个域名,且必须是已备案的域名
二、微信登录流程
流程图
用户点击微信登录
↓
跳转到微信授权页面
↓
用户授权后,微信回调到你的网站(带code参数)
↓
前端将code发送给后端
↓
后端用code换取access_token
↓
后端用access_token获取用户信息
↓
后端处理登录逻辑,返回token给前端
↓
前端保存token,完成登录
三、前端实现
1. 添加微信登录API方法
在 src/api/auth.js 中添加:
// 微信登录 - 获取授权URL
getWechatAuthUrl: () => {
const appId = process.env.REACT_APP_WECHAT_APPID; // 从环境变量读取
const redirectUri = encodeURIComponent(
`${window.location.origin}/login/wechat/callback`
);
const state = Math.random().toString(36).substring(7); // 防止CSRF攻击
localStorage.setItem('wechat_state', state);
return `https://open.weixin.qq.com/connect/qrconnect?appid=${appId}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_login&state=${state}#wechat_redirect`;
},
// 微信登录 - 用code换取token
wechatLogin: async (code, state) => {
try {
const { data } = await axios.post('/productx/user/wechat-login', {
code,
state
});
if (data.success) {
const token = data.data.token;
localStorage.setItem('token', token);
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`;
// 获取用户信息
const userInfoResult = await auth.getUserInfo();
if (!userInfoResult.success) {
return { success: false, message: '获取用户信息失败' };
}
return { success: true };
}
return data;
} catch (error) {
return {
success: false,
message: error.response?.data?.message || '微信登录失败'
};
}
}
2. 添加微信登录按钮点击事件
在 src/pages/Login/components/RightSection/index.js 中:
import { auth } from '../../../../api/auth';
import { useNavigate } from 'react-router-dom';
export const RightSection = ({
// ... 其他props
locale
}) => {
const navigate = useNavigate();
// 处理微信登录
const handleWechatLogin = () => {
const authUrl = auth.getWechatAuthUrl();
window.location.href = authUrl; // 跳转到微信授权页面
};
// ... 其他代码
return (
// ... 其他JSX
<SocialButton
type="button"
socialType="wechat"
index={0}
title="微信登录"
onClick={handleWechatLogin}
>
<SiWechat />
</SocialButton>
// ... 其他JSX
);
};
3. 创建微信登录回调页面
创建 src/pages/Login/WechatCallback.js:
import React, { useEffect } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { message } from 'antd';
import { auth } from '../../api/auth';
const WechatCallback = () => {
const navigate = useNavigate();
const [searchParams] = useSearchParams();
useEffect(() => {
const handleCallback = async () => {
const code = searchParams.get('code');
const state = searchParams.get('state');
const savedState = localStorage.getItem('wechat_state');
// 验证state,防止CSRF攻击
if (!state || state !== savedState) {
message.error('登录失败:状态验证失败');
navigate('/login');
return;
}
// 清除保存的state
localStorage.removeItem('wechat_state');
if (!code) {
message.error('登录失败:未获取到授权码');
navigate('/login');
return;
}
// 显示加载提示
message.loading('正在登录...', 0);
try {
const result = await auth.wechatLogin(code, state);
if (result.success) {
message.destroy();
message.success('登录成功');
navigate('/workspace');
} else {
message.destroy();
message.error(result.message || '登录失败');
navigate('/login');
}
} catch (error) {
message.destroy();
message.error('登录失败,请稍后重试');
navigate('/login');
}
};
handleCallback();
}, [searchParams, navigate]);
return (
<div style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100vh'
}}>
<div>正在处理微信登录...</div>
</div>
);
};
export default WechatCallback;
4. 添加路由
在 src/App.js 中添加:
import WechatCallback from './pages/Login/WechatCallback';
// 在Routes中添加
<Route path="/login/wechat/callback" element={<WechatCallback />} />
5. 配置环境变量
在项目根目录创建 .env 文件(如果还没有):
REACT_APP_WECHAT_APPID=你的微信AppID
四、后端实现
1. 后端接口:/productx/user/wechat-login
请求参数:
{
"code": "微信返回的授权码",
"state": "防止CSRF的状态码"
}
后端处理流程:
// 伪代码示例(Node.js/Express)
app.post('/productx/user/wechat-login', async (req, res) => {
const { code, state } = req.body;
const appId = process.env.WECHAT_APPID;
const appSecret = process.env.WECHAT_APPSECRET;
try {
// 1. 用code换取access_token
const tokenResponse = await axios.get(
`https://api.weixin.qq.com/sns/oauth2/access_token`,
{
params: {
appid: appId,
secret: appSecret,
code: code,
grant_type: 'authorization_code'
}
}
);
const { access_token, openid, unionid } = tokenResponse.data;
if (!access_token) {
return res.json({
success: false,
message: '获取access_token失败'
});
}
// 2. 用access_token获取用户信息
const userInfoResponse = await axios.get(
`https://api.weixin.qq.com/sns/userinfo`,
{
params: {
access_token: access_token,
openid: openid
}
}
);
const { nickname, headimgurl, sex, province, city } = userInfoResponse.data;
// 3. 根据openid或unionid查找或创建用户
let user = await User.findOne({
$or: [
{ wechatOpenId: openid },
{ wechatUnionId: unionid }
]
});
if (!user) {
// 创建新用户
user = await User.create({
username: `wx_${openid.substring(0, 8)}`,
nickname: nickname,
avatar: headimgurl,
wechatOpenId: openid,
wechatUnionId: unionid,
gender: sex === 1 ? 'male' : sex === 2 ? 'female' : 'unknown',
province: province,
city: city,
loginType: 'wechat'
});
} else {
// 更新用户信息
user.nickname = nickname;
user.avatar = headimgurl;
user.lastLoginAt = new Date();
await user.save();
}
// 4. 生成JWT token
const token = generateToken(user);
// 5. 返回token
res.json({
success: true,
data: {
token: token,
user: {
id: user._id,
username: user.username,
nickname: user.nickname,
avatar: user.avatar
}
}
});
} catch (error) {
console.error('微信登录错误:', error);
res.json({
success: false,
message: '微信登录失败'
});
}
});
2. 数据库用户表字段
需要在用户表中添加以下字段:
wechatOpenId- 微信OpenID(唯一标识)wechatUnionId- 微信UnionID(跨应用统一标识,可选)loginType- 登录方式(‘email’, ‘wechat’, 'qq’等)
五、注意事项
1. 安全性
- ✅ 必须验证
state参数,防止CSRF攻击 - ✅
AppSecret必须保存在后端,不能暴露在前端 - ✅ 使用HTTPS协议
- ✅ 验证回调URL的域名
2. 用户体验
- ✅ 登录成功后自动跳转到目标页面
- ✅ 显示加载状态,避免用户重复点击
- ✅ 错误提示要友好
3. 错误处理
- 用户取消授权:微信会返回
error参数 - code过期:code只能使用一次,且5分钟内有效
- 网络错误:需要重试机制
4. 测试
- 使用微信开放平台提供的测试账号
- 在本地开发时,可以使用内网穿透工具(如ngrok)来测试回调
六、常见问题
Q1: 回调域名必须备案吗?
A: 是的,微信要求回调域名必须是已备案的域名。
Q2: 本地开发如何测试?
A: 可以使用内网穿透工具(如ngrok、natapp)将本地地址映射到公网域名。
Q3: UnionID和OpenID的区别?
A:
- OpenID:同一用户在不同应用中的标识不同
- UnionID:同一用户在同一开发者账号下的所有应用中标识相同
- 建议同时保存UnionID,方便多应用统一用户体系
Q4: 如何实现微信扫码登录?
A: 使用 qrconnect 接口(本指南已使用),会自动显示二维码。如果是PC端,可以显示二维码让用户扫码。
七、参考文档
- 微信开放平台文档:https://developers.weixin.qq.com/doc/oplatform/Website_App/WeChat_Login/Wechat_Login.html
- 微信登录接口文档:https://developers.weixin.qq.com/doc/oplatform/en/Website_App/WeChat_Login/Wechat_Login.html
更多推荐



所有评论(0)