7.7 KiB
7.7 KiB
微信小程序最终登录方案
方案说明
采用自动静默登录方案,用户打开小程序即自动完成登录,无需任何授权操作。
实现方式
1. 进入首页自动登录
- 用户打开小程序,进入首页
- 检查本地缓存,如果有登录信息,直接使用
- 如果没有缓存,自动调用
wx.login获取 code - 使用 code 调用后端 identify 接口完成登录
- 全程无需用户操作
2. 登录流程
用户打开小程序
↓
进入首页 (pages/index/index)
↓
检查缓存 (token, userInfo, wechatId)
↓
有缓存 → 直接使用
↓
无缓存 → 自动登录
↓
wx.login 获取 code
↓
调用 identify 接口
↓
保存登录信息
↓
完成登录
3. Token 过期处理
API 请求返回 401
↓
清除缓存
↓
提示"登录已过期,正在重新登录"
↓
刷新页面
↓
触发自动登录
4. 退出登录
点击"退出"按钮
↓
确认对话框
↓
清除登录信息
↓
调用 autoLogin() 重新登录
代码实现
首页 (pages/index/index.uvue)
// 初始化用户信息
async function initUserInfo() {
try {
// 1. 先尝试从缓存获取
const cachedWechatId = uni.getStorageSync('wechatId')
const cachedUserInfo = uni.getStorageSync('userInfo')
const cachedToken = uni.getStorageSync('token')
if (cachedWechatId && cachedUserInfo && cachedToken) {
// 有完整缓存,直接使用
const parsedUserInfo = typeof cachedUserInfo === 'string'
? JSON.parse(cachedUserInfo)
: cachedUserInfo
userInfo.value = {
wechatId: cachedWechatId,
username: parsedUserInfo.username || parsedUserInfo.realName || '微信用户',
phone: parsedUserInfo.phone || '',
userId: parsedUserInfo.userId || ''
}
// 判断用户类型
userType.value = parsedUserInfo.status !== 'guest'
console.log('使用缓存的用户信息:', userInfo.value)
return
}
// 2. 没有缓存,自动登录
await autoLogin()
} catch (error) {
console.error('初始化用户信息失败:', error)
await autoLogin()
}
}
// 自动登录
async function autoLogin() {
uni.showLoading({ title: '登录中...' })
try {
uni.login({
provider: 'weixin',
success: async (loginRes) => {
console.log('微信登录成功,code:', loginRes.code)
const code = loginRes.code
const wechatId = code.substring(0, 20) // 使用部分code作为临时ID
// 调用 identify 接口
const identifyRes = await guestAPI.identify({
wechatId: wechatId,
phone: ''
})
uni.hideLoading()
if (identifyRes.success && identifyRes.data) {
const loginDomain = identifyRes.data
// 保存登录信息
uni.setStorageSync('token', loginDomain.token || '')
uni.setStorageSync('userInfo', JSON.stringify(loginDomain.user))
uni.setStorageSync('loginDomain', JSON.stringify(loginDomain))
uni.setStorageSync('wechatId', wechatId)
// 更新用户信息
userInfo.value = {
wechatId: wechatId,
username: loginDomain.user?.username || loginDomain.user?.realName || '微信用户',
phone: loginDomain.user?.phone || '',
userId: loginDomain.user?.userId || ''
}
// 判断用户类型
userType.value = loginDomain.user?.status !== 'guest'
console.log('自动登录成功:', userInfo.value)
} else {
uni.showToast({
title: identifyRes.message || '登录失败',
icon: 'none'
})
}
},
fail: (err) => {
console.error('微信登录失败:', err)
uni.hideLoading()
uni.showToast({ title: '登录失败,请重试', icon: 'none' })
}
})
} catch (error: any) {
console.error('自动登录失败:', error)
uni.hideLoading()
uni.showToast({
title: error.message || '登录失败',
icon: 'none'
})
}
}
优势
1. 用户体验极佳
- ✅ 无需任何授权操作
- ✅ 打开即用
- ✅ 无感知登录
- ✅ 无弹窗干扰
2. 无权限要求
- ✅ 不需要企业认证
- ✅ 不需要开通手机号快速验证
- ✅ 个人小程序也可使用
- ✅ 测试环境友好
3. 代码简洁
- ✅ 删除了授权页面
- ✅ 删除了切换用户功能
- ✅ 删除了所有 mock 相关代码
- ✅ 只保留核心登录逻辑
4. 维护方便
- ✅ 登录逻辑集中在首页
- ✅ Token 过期自动处理
- ✅ 错误处理完善
- ✅ 日志清晰
后端要求
identify 接口
POST /urban-lifeline/system/guest/identify
{
"wechatId": "微信ID(使用code的前20位作为临时标识)",
"phone": "" // 可以为空
}
返回:
{
"success": true,
"data": {
"token": "jwt_token",
"user": {
"userId": "用户ID",
"username": "用户名",
"realName": "真实姓名",
"phone": "手机号(可能为空)",
"status": "guest" | "employee"
}
}
}
建议优化
-
后端可以通过 code 换取 openid
- 前端传递完整的 code
- 后端调用微信 API 换取 openid
- 使用 openid 作为用户唯一标识
-
支持游客模式
- 如果 wechatId 不存在,创建游客账号
- 返回游客身份的 token
- 允许后续绑定手机号升级为正式用户
已删除的内容
1. 授权页面
- ❌
pages/auth/auth.uvue- 已删除 - ❌ pages.json 中的 auth 路由配置 - 已删除
2. 切换用户功能
- ❌
switchMockUser()函数 - 已删除 - ❌
isMockMode变量 - 已删除 - ❌ 切换按钮 UI - 已删除
- ❌ 所有条件编译代码 - 已删除
3. getUserProfile
- ❌ 不再使用
getUserProfileAPI - ❌ 不再需要用户授权昵称
4. getPhoneNumber
- ❌ 不再使用
getPhoneNumberAPI - ❌ 不再需要手机号授权
保留的功能
1. 退出登录
- ✅ 右上角"退出"按钮
- ✅ 点击后清除缓存并重新自动登录
- ✅ 红色主题,易于识别
2. Token 管理
- ✅ 自动检测 401 错误
- ✅ 自动清除过期信息
- ✅ 自动重新登录
3. 用户类型识别
- ✅ 区分 guest 和 employee
- ✅ 根据类型控制功能权限
测试清单
首次使用
- 打开小程序,自动登录成功
- 无任何授权弹窗
- 用户信息正确显示
- 可以正常使用所有功能
再次使用
- 关闭小程序重新打开
- 直接进入首页,无需重新登录
- 用户信息保持不变
Token 过期
- 模拟 Token 过期(后端返回 401)
- 自动提示"登录已过期,正在重新登录"
- 自动完成重新登录
- 功能恢复正常
退出登录
- 点击"退出"按钮
- 显示确认对话框
- 确认后自动重新登录
- 登录成功后可正常使用
API 请求
- 所有 API 请求携带正确的 token
- 请求路径正确(/urban-lifeline/)
- WebSocket 连接正常
- 文件上传功能正常
部署说明
1. 编译
npm run build:mp-weixin
2. 上传
- 使用微信开发者工具打开
unpackage/dist/build/mp-weixin - 点击"上传"按钮
- 填写版本号和备注
3. 提交审核
- 登录微信公众平台
- 进入"版本管理"
- 提交审核
4. 发布
- 审核通过后,点击"发布"
- 用户即可使用
总结
当前方案是最简洁、最友好的登录方案:
- ✅ 无需任何用户操作
- ✅ 无需小程序认证
- ✅ 代码简洁易维护
- ✅ 用户体验极佳
- ✅ 适用于所有场景
可以直接部署使用!