UniApp + UniCloud 实现微信小程序静默登录

UniApp + UniCloud 实现微信小程序静默登录

目录

  • [1. 项目准备](#1. 项目准备)
  • [2. UniCloud 配置](#2. UniCloud 配置)
  • [3. 前端实现](#3. 前端实现)
  • [4. 云函数实现](#4. 云函数实现)
  • [5. 完整示例](#5. 完整示例)

1. 项目准备

1.1 环境要求

  • HBuilderX 3.0+
  • 微信开发者工具
  • UniCloud 已开通
  • 微信小程序已注册

1.2 项目配置

  1. 在 manifest.json 中配置微信小程序 AppID:
json 复制代码
{
  "mp-weixin": {
    "appid": "你的小程序AppID",
    "setting": {
      "urlCheck": false
    }
  }
}
  1. 在 pages.json 中添加登录页面:
json 复制代码
{
  "pages": [
    {
      "path": "pages/index/index",
      "style": {
        "navigationBarTitleText": "首页"
      }
    }
  ]
}

2. UniCloud 配置

2.1 数据库集合创建

  1. 创建用户集合 uni-id-users
json 复制代码
{
  "bsonType": "object",
  "required": ["_id"],
  "properties": {
    "_id": {
      "description": "ID,系统自动生成",
      "bsonType": "string"
    },
    "wx_openid": {
      "bsonType": "string",
      "description": "微信openid"
    },
    "wx_unionid": {
      "bsonType": "string",
      "description": "微信unionid"
    },
    "session_key": {
      "bsonType": "string",
      "description": "微信会话密钥"
    }
  }
}

2.2 uni-config-center 配置

uniCloud/cloudfunctions/common/uni-config-center/uni-id/config.json 中配置:

json 复制代码
{
  "mp-weixin": {
    "appid": "你的小程序AppID",
    "appsecret": "你的小程序AppSecret"
  }
}

3. 前端实现

3.1 登录工具类

创建 utils/login.js

javascript 复制代码
export default class LoginManager {
  static async silentLogin() {
    try {
      // 获取微信登录凭证
      const { code } = await uni.login({
        provider: 'weixin'
      });
      
      // 调用云函数登录
      const { result } = await uniCloud.callFunction({
        name: 'wx-silent-login',
        data: { code }
      });
      
      // 保存登录状态
      if (result.token) {
        uni.setStorageSync('uni_id_token', result.token);
        uni.setStorageSync('uni_id_token_expired', result.tokenExpired);
      }
      
      return result;
    } catch (e) {
      console.error('静默登录失败:', e);
      throw e;
    }
  }
  
  static async checkLoginState() {
    const token = uni.getStorageSync('uni_id_token');
    const tokenExpired = uni.getStorageSync('uni_id_token_expired');
    
    if (!token || !tokenExpired || tokenExpired < Date.now()) {
      return await this.silentLogin();
    }
    
    return { token, tokenExpired };
  }
}

3.2 页面使用

pages/index/index.vue 中:

vue 复制代码
<template>
  <view class="content">
    <text>{{userInfo ? '已登录' : '未登录'}}</text>
  </view>
</template>

<script>
import LoginManager from '@/utils/login.js'

export default {
  data() {
    return {
      userInfo: null
    }
  },
  onLoad() {
    this.checkLogin()
  },
  methods: {
    async checkLogin() {
      try {
        const loginState = await LoginManager.checkLoginState()
        if (loginState.userInfo) {
          this.userInfo = loginState.userInfo
        }
      } catch (e) {
        console.error(e)
      }
    }
  }
}
</script>

4. 云函数实现

4.1 创建云函数

创建 uniCloud/cloudfunctions/wx-silent-login/index.js

javascript 复制代码
'use strict';
const uniID = require('uni-id-common')

exports.main = async function(event, context) {
  const { code } = event
  const uniIDIns = uniID.createInstance({ context })
  
  try {
    // 微信登录
    const wxLoginRes = await uniIDIns.loginByWeixin({
      code
    })
    
    // 如果是新用户,可以在这里进行额外处理
    if (wxLoginRes.type === 'register') {
      // 可以在这里添加用户初始化逻辑
    }
    
    return {
      errCode: 0,
      token: wxLoginRes.token,
      tokenExpired: wxLoginRes.tokenExpired,
      userInfo: wxLoginRes.userInfo
    }
  } catch (e) {
    return {
      errCode: e.errCode || -1,
      errMsg: e.errMsg || '登录失败'
    }
  }
}

5. 完整示例

5.1 登录流程

  1. 应用启动时检查登录状态
  2. 如果未登录或登录过期,进行静默登录
  3. 获取 code 并调用云函数
  4. 云函数处理登录逻辑并返回结果
  5. 前端保存登录状态

5.2 示例代码

App.vue 中:

vue 复制代码
<script>
import LoginManager from '@/utils/login.js'

export default {
  onLaunch: async function() {
    try {
      await LoginManager.checkLoginState()
    } catch (e) {
      console.error('登录失败:', e)
    }
  }
}
</script>

5.3 登录拦截器

创建 utils/request.js

javascript 复制代码
const httpInterceptor = {
  invoke(options) {
    // 添加token
    const token = uni.getStorageSync('uni_id_token')
    if (token) {
      options.header = {
        ...options.header,
        'x-token': token
      }
    }
    
    // 请求拦截
    return options
  },
  success(response) {
    // 如果token过期,尝试重新登录
    if (response.data.errCode === 'TOKEN_INVALID') {
      LoginManager.silentLogin()
    }
    return response
  }
}

uni.addInterceptor('request', httpInterceptor)
uni.addInterceptor('uploadFile', httpInterceptor)

注意事项

  1. 确保微信小程序的 AppID 和 AppSecret 配置正确
  2. 处理好登录失败的情况
  3. 注意 token 的有效期管理
  4. 考虑数据安全性,避免敏感信息泄露
  5. 建议添加请求重试机制

参考资源

相关推荐
换日线°1 天前
NFC标签打开微信小程序
前端·微信小程序
局外人LZ1 天前
Uniapp脚手架项目搭建,uniapp+vue3+uView pro+vite+pinia+sass
前端·uni-app·sass
2501_915918411 天前
在 iOS 环境下查看 App 详细信息与文件目录
android·ios·小程序·https·uni-app·iphone·webview
前端呆头鹅1 天前
Websocket使用方案详解(uniapp版)
websocket·网络协议·uni-app
浮桥1 天前
uniapp+h5 公众号实现分享海报绘制
uni-app·notepad++
2501_916007471 天前
没有 Mac 用户如何上架 App Store,IPA生成、证书与描述文件管理、跨平台上传
android·macos·ios·小程序·uni-app·iphone·webview
wangjun51592 天前
uniapp uni.downloadFile 偶发性下载文件失败 无响应
uni-app
菜鸟una2 天前
【微信小程序+Taro 3+NutUI 3】input (nut-input) 、 textarea (nut-texteare)类型使用避坑
前端·vue.js·微信小程序·小程序·taro
计算机毕设指导62 天前
基于微信小程序的校园二手交易系统【源码文末联系】
java·spring boot·spring·微信小程序·小程序·tomcat·maven
2501_915106322 天前
当 Perfdog 开始收费之后,我重新整理了一替代方案
android·ios·小程序·https·uni-app·iphone·webview