核心是后端用uni-id统一签发jwt,前端各端只认此token;所有登录入口必须调用uni-id登录接口,provider须严格区分,token存storage并由拦截器自动携带authorization头。

uni-app + uniCloud 实现多终端统一鉴权,核心不是前端“做对登录”,而是后端用 uni-id 统一发 token、前端所有端都只认这个 token——App、小程序、H5 各自走各自的登录流程,但最终都必须换回同一个 uni-id 签发的 JWT。
uni-id 是唯一可信的鉴权中心,不是可选模块
uniCloud 官方的 uni-id 不是“辅助工具”,它是整个鉴权体系的地基。一旦启用,所有登录入口(微信小程序 uni.login、App 微信登录、短信验证码、邮箱密码)都必须调用 uniCloud.callFunction({ name: 'uniIdLogin' }) 或其封装接口(如 uniId.loginWithWeixin),由 uni-id 生成并返回标准 JWT。跳过它直接自己签 token,等于放弃权限同步、设备管理、token 刷新等能力。
- 前端不能自己拼
Authorizationheader,必须从uni-id返回结果里取token字段 - 后端云函数必须用
uniID.checkToken()校验,而不是手动jwt.verify() -
uni-id-users表是唯一用户主表,App 和小程序登录成功后,必须落到同一行记录(靠unionId或手机号去重合并)
各端登录后必须调用 uni-id 统一登录接口
不同端获取的原始凭证差异极大,但都必须交给 uni-id 处理:
- 微信小程序:拿到
code后,传给云函数uniId.loginWithWeixin({ code }),不能自己调用微信后台接口 - App 微信登录:
uni.login({ provider: 'weixin-app' })返回的是authCode,不是小程序的code,要传uniId.loginWithWeixin({ authCode, provider: 'weixin-app' }) - H5 微信扫码:走 OAuth2 授权码模式,回调地址必须指向你的云函数,由函数内调
uniId.loginWithWeixin({ code, provider: 'weixin-h5' }) - 短信登录:前端传手机号+验证码,云函数调
uniId.loginWithSms({ phone, code }),uni-id自动查库、发 token
关键点:provider 值必须严格区分(weixin / weixin-app / weixin-h5),否则 uni-id 无法正确路由到对应平台 SDK,会报 provider not supported 错误。
token 存储与自动携带必须全局统一
前端不关心 token 类型或过期逻辑,只负责存、取、透传:
- 登录成功后立刻执行
uni.setStorageSync('token', res.token),不要用uni.setStorage(异步风险高) - 全局请求拦截必须用
uni.interceptor,且 header 中的 key 必须是Authorization,值格式为Bearer ${token} - 401 响应必须触发重新登录,但不要直接跳转登录页——先尝试
uniId.refreshToken(),失败再跳;否则用户在 App 里切后台再回来就强制登出 - H5 端注意:
localStorage无跨域共享,但uni.setStorageSync在 H5 下实际写的是localStorage,所以 H5 多标签页之间 token 不同步,这是设计使然,不是 bug
App 端真机调试必须用自定义基座,且 manifest 配置不能漏
App 端 OAuth 模块不生效,90% 是因为没走完整流程:
- manifest.json 的 “App模块配置” → “OAuth(登录鉴权)” 必须勾选,且下方微信/支付宝等平台的 AppID、密钥必须填全
- 这些配置**仅云端打包后生效**,真机运行时若用普通基座,
uni.login会静默失败或返回空对象 - 必须用 HBuilderX 打包“自定义基座”,安装到手机后才能调试登录流程;开发阶段别依赖“运行到手机”快捷按钮
- Android 12+ 要求 targetSdkVersion ≥ 31,微信 App 登录需额外在
android/res/xml/network_security_config.xml中声明允许 cleartextTraffic,否则authCode无法上传
最易被忽略的是:App 端登录成功后,uni.getUserInfo 返回的 userInfo 是空对象(因系统级登录不提供头像昵称),别指望它和小程序一样有数据——用户资料得靠后端 uni-id 的 getUserInfo 云函数查 uni-id-users 表补全。











