微信小程序的登录流程涉及小程序前端、开发者服务器和微信接口服务的交互。以下是完整的登录流程解析:
基本登录流程
-
前端调用 wx.login()
-
小程序端调用此API获取临时登录凭证(code)
-
有效期5分钟,且一次性使用
wx.login({ success: res => { const code = res.code; // 获取临时登录凭证 // 发送code到开发者服务器 } });
-
-
发送code到开发者服务器
-
小程序将code发送到开发者自己的后端服务器
-
-
服务器请求微信接口
-
开发者服务器使用code、appid和appsecret请求微信接口
-
接口地址:
https://api.weixin.qq.com/sns/jscode2session
-
参数:
-
appid
: 小程序ID -
secret
: 小程序密钥 -
js_code
: 前端获取的code -
grant_type
: authorization_code
-
-
-
微信返回session_key和openid
-
成功响应示例:
{ "openid": "用户唯一标识", "session_key": "会话密钥", "unionid": "用户在开放平台的唯一标识符(如果满足条件)" }
-
-
生成自定义登录态
-
开发者服务器生成自己的session标识
-
将session与openid/session_key关联存储
-
返回自定义登录态给小程序
-
-
小程序存储登录态
-
小程序将自定义登录态存储在storage中
-
后续请求携带此登录态
wx.setStorageSync('auth_token', serverSessionId);
-
完整流程示意图
小程序前端 开发者服务器 微信接口服务
| | |
|--- wx.login() ---->| |
|<--- 返回code ------| |
| | |
|--- 发送code -------> |
| |--- code2session --->|
| |<--- session_key ----|
| | openid |
|<--- 返回自定义登录态--| |
| | |
安全注意事项
-
AppSecret保护
-
永远不要在前端存储或使用AppSecret
-
所有需要AppSecret的操作必须在服务器完成
-
-
SessionKey保护
-
SessionKey不应传到小程序端
-
它是微信服务器与开发者服务器之间的密钥
-
-
通信安全
-
所有敏感数据传输应使用HTTPS
-
小程序端与服务器通信应加密敏感数据
-
-
登录态校验
-
每次请求验证登录态有效性
-
设置合理的登录态过期时间
-
最佳实践
-
登录态管理
-
使用token机制管理登录态
-
设置合理的过期时间(如7天)
-
提供刷新token的机制
-
-
用户信息获取
-
通过
<button open-type="getUserInfo">
获取用户信息 -
需要用户授权后才能获取
-
-
UnionID获取
-
如果小程序绑定到微信开放平台,可以获取unionid
-
需要用户在不同公众号/小程序间统一身份时使用
-
-
异常处理
-
处理code过期情况
-
处理微信接口调用失败情况
-
提供友好的重新登录机制
-
代码示例(完整流程)
小程序端代码:
// 登录函数
function login() {
// 1. 获取code
wx.login({
success: res => {
if (res.code) {
// 2. 发送code到服务器
wx.request({
url: 'https://your-server.com/api/login',
method: 'POST',
data: { code: res.code },
success: res => {
// 5. 存储服务器返回的自定义登录态
if (res.data.token) {
wx.setStorageSync('auth_token', res.data.token);
// 登录成功,继续获取用户信息等
getUserProfile();
}
}
});
}
}
});
}
// 获取用户信息
function getUserProfile() {
wx.getUserProfile({
desc: '用于完善会员资料',
success: res => {
// 将用户信息发送到服务器保存
wx.request({
url: 'https://your-server.com/api/userinfo',
method: 'POST',
header: {
'Authorization': 'Bearer ' + wx.getStorageSync('auth_token')
},
data: res.userInfo
});
}
});
}
服务器端示例(Node.js):
const axios = require('axios');
const jwt = require('jsonwebtoken');
async function login(req, res) {
const { code } = req.body;
try {
// 3. 使用code换取session_key和openid
const result = await axios.get('https://api.weixin.qq.com/sns/jscode2session', {
params: {
appid: '你的小程序appid',
secret: '你的小程序secret',
js_code: code,
grant_type: 'authorization_code'
}
});
const { openid, session_key } = result.data;
// 4. 生成自定义登录态
const token = jwt.sign({ openid }, '你的服务器密钥', { expiresIn: '7d' });
// 5. 返回token给小程序
res.json({ token });
// 注意:session_key应存储在服务器,不要返回给客户端
} catch (error) {
res.status(401).json({ error: '登录失败' });
}
}
通过以上流程,微信小程序可以实现安全可靠的用户登录系统。