当前位置: 首页 > article >正文

uni-app微信小程序登录流程详解

文章目录

  • uni-app微信小程序登录流程实战详解
    • 微信小程序登录流程概述
    • 1. 获取登录凭证(code)
    • 2. 发送登录请求
    • 3. 保存登录态
    • 4. 登录状态管理
    • 5. 应用登录状态
      • 请求拦截器中添加 token
      • 自动登录
      • 页面路由守卫
    • 使用 Vuex 集中管理登录状态
    • 登录组件示例
    • 登录流程最佳实践
    • 总结

uni-app微信小程序登录流程实战详解

作为前端开发者,理解微信小程序的登录流程对构建用户认证系统至关重要。本文将从前端开发角度,详细介绍如何在uni-app框架下实现微信小程序的登录流程,包括获取登录凭证、发送登录请求、管理登录状态等关键环节。

微信小程序登录流程概述

微信小程序的前端登录流程主要包括以下几个步骤:

  1. 调用 uni.login() 获取登录凭证(code)
  2. 将 code 发送到自己的业务服务器
  3. 接收服务器返回的登录态(token)
  4. 保存并管理登录态
  5. 在后续请求中使用登录态

接下来,我们将详细解析每个步骤的实现。

1. 获取登录凭证(code)

在小程序启动时,我们首先需要调用 uni.login() 方法获取登录凭证(code):

// 获取微信登录凭证
function getWxLoginCode() {return new Promise((resolve, reject) => {uni.login({provider: 'weixin',success: (res) => {if (res.code) {console.log('登录凭证获取成功');resolve(res.code);} else {console.error('登录凭证获取失败:', res.errMsg);reject(new Error(res.errMsg));}},fail: (err) => {console.error('登录接口调用失败:', err);reject(err);}});});
}

这段代码封装了 uni.login() 方法,返回一个 Promise 对象,便于我们使用 async/await 语法处理异步流程。

2. 发送登录请求

获取到 code 后,我们需要将其发送到自己的业务服务器,以换取自定义登录态:

// 发送登录请求
async function login() {try {// 显示加载提示uni.showLoading({title: '登录中...'});// 获取微信登录凭证const code = await getWxLoginCode();// 发送登录请求const result = await request({url: '/api/user/login',method: 'POST',data: { code }});// 处理登录结果if (result.code === 0 && result.data) {// 登录成功,保存登录态saveLoginState(result.data);return result.data;} else {// 登录失败uni.showToast({title: result.msg || '登录失败',icon: 'none'});return null;}} catch (error) {// 处理错误console.error('登录过程发生错误:', error);uni.showToast({title: '登录失败,请重试',icon: 'none'});return null;} finally {// 隐藏加载提示uni.hideLoading();}
}

这段代码完成了以下工作:

  • 调用 getWxLoginCode() 获取登录凭证
  • 将 code 发送到业务服务器
  • 处理服务器返回的登录结果
  • 提供用户友好的反馈(加载提示、错误提示)

3. 保存登录态

当服务器返回登录态(通常是 token)后,我们需要将其保存起来:

// 保存登录状态
function saveLoginState(loginData) {// 保存 token 到本地存储uni.setStorageSync('token', loginData.token);// 保存用户信息if (loginData.userInfo) {uni.setStorageSync('userInfo', loginData.userInfo);}// 记录登录时间uni.setStorageSync('loginTime', Date.now());console.log('登录状态已保存');
}

在这里,我们使用 uni-app 提供的存储 API 保存了 token、用户信息和登录时间。这些信息将在后续的请求和页面中使用。

4. 登录状态管理

为了有效管理登录状态,我们需要提供一套完整的工具函数:

// 检查是否已登录
function isLoggedIn() {return !!uni.getStorageSync('token');
}// 获取当前token
function getToken() {return uni.getStorageSync('token') || '';
}// 获取用户信息
function getUserInfo() {return uni.getStorageSync('userInfo') || null;
}// 清除登录状态
function clearLoginState() {uni.removeStorageSync('token');uni.removeStorageSync('userInfo');uni.removeStorageSync('loginTime');
}// 检查登录是否过期
function isLoginExpired() {const loginTime = uni.getStorageSync('loginTime') || 0;const currentTime = Date.now();// 假设登录有效期为7天const expiresIn = 7 * 24 * 60 * 60 * 1000;return currentTime - loginTime > expiresIn;
}// 刷新登录状态
async function refreshLogin() {if (isLoginExpired()) {clearLoginState();return await login();}return true;
}

这组函数提供了:

  • 检查用户是否已登录
  • 获取 token 和用户信息
  • 清除登录状态
  • 检查登录是否过期
  • 刷新登录状态

5. 应用登录状态

有了上述工具函数,我们需要在应用中合理使用它们:

请求拦截器中添加 token

// 请求拦截器
const request = (options) => {// 克隆原始选项const requestOptions = {...options,header: options.header || {}};// 添加 token 到请求头const token = getToken();if (token) {requestOptions.header.Authorization = `Bearer ${token}`;}// 发送请求return new Promise((resolve, reject) => {uni.request({...requestOptions,success: (res) => {// 检查响应状态if (res.statusCode === 200) {resolve(res.data);} else if (res.statusCode === 401) {// token 无效或过期handleUnauthorized();reject(new Error('未授权'));} else {reject(res);}},fail: (err) => {reject(err);}});});
};// 处理未授权情况
function handleUnauthorized() {// 清除登录状态clearLoginState();// 提示用户uni.showToast({title: '登录已过期,请重新登录',icon: 'none'});// 跳转到登录页setTimeout(() => {uni.navigateTo({url: '/pages/login/login'});}, 1500);
}

这个请求拦截器确保了:

  • 每个请求都带上 token
  • 处理 401 未授权响应
  • 在 token 无效时引导用户重新登录

自动登录

在应用启动时,我们可以实现自动登录功能:

// App.vue 的 onLaunch 钩子
export default {async onLaunch() {// 检查本地是否有登录态if (isLoggedIn()) {// 检查登录是否过期if (isLoginExpired()) {console.log('登录已过期,尝试重新登录');await login();} else {console.log('已登录状态');}} else {console.log('未登录状态');await login();}}
}

这段代码在应用启动时检查登录状态,并在必要时进行自动登录。

页面路由守卫

在需要登录才能访问的页面,我们可以添加路由守卫:

// 需要登录的页面
export default {onLoad() {this.checkLogin();},methods: {checkLogin() {if (!isLoggedIn()) {uni.showToast({title: '请先登录',icon: 'none'});// 跳转到登录页setTimeout(() => {uni.navigateTo({url: '/pages/login/login'});}, 1500);return false;}return true;}}
}

使用 Vuex 集中管理登录状态

为了更好地管理状态,我们可以使用 Vuex:

// store/modules/user.js
const state = {token: uni.getStorageSync('token') || '',userInfo: uni.getStorageSync('userInfo') || null
};const mutations = {SET_TOKEN(state, token) {state.token = token;uni.setStorageSync('token', token);},SET_USER_INFO(state, userInfo) {state.userInfo = userInfo;uni.setStorageSync('userInfo', userInfo);},CLEAR_USER(state) {state.token = '';state.userInfo = null;uni.removeStorageSync('token');uni.removeStorageSync('userInfo');uni.removeStorageSync('loginTime');}
};const actions = {// 登录async login({ commit }) {try {uni.showLoading({ title: '登录中...' });// 获取微信登录凭证const code = await getWxLoginCode();// 发送登录请求const result = await request({url: '/api/user/login',method: 'POST',data: { code }});if (result.code === 0 && result.data) {// 保存登录状态commit('SET_TOKEN', result.data.token);commit('SET_USER_INFO', result.data.userInfo);uni.setStorageSync('loginTime', Date.now());return result.data;} else {uni.showToast({title: result.msg || '登录失败',icon: 'none'});return null;}} catch (error) {console.error('登录失败', error);uni.showToast({title: '登录失败,请重试',icon: 'none'});return null;} finally {uni.hideLoading();}},// 登出logout({ commit }) {commit('CLEAR_USER');uni.reLaunch({url: '/pages/login/login'});},// 检查登录状态checkLogin({ state, dispatch }) {if (!state.token) {return false;}const loginTime = uni.getStorageSync('loginTime') || 0;const currentTime = Date.now();const expiresIn = 7 * 24 * 60 * 60 * 1000;if (currentTime - loginTime > expiresIn) {// 登录过期,重新登录return dispatch('login');}return true;}
};export default {namespaced: true,state,mutations,actions
};

使用 Vuex 管理登录状态有以下优势:

  • 集中管理状态
  • 状态变化更加可预测
  • 方便组件之间共享状态
  • 提供统一的 API 接口

登录组件示例

最后,我们来看一个完整的登录组件示例:

<!-- pages/login/login.vue -->
<template><view class="login-container"><image class="logo" src="/static/logo.png"></image><view class="welcome">欢迎使用向明天小程序</view><button class="login-btn" type="primary" :loading="loading"@click="handleLogin">微信一键登录</button><view class="tips">登录后即可使用完整功能</view></view>
</template><script>
import { mapActions } from 'vuex';export default {data() {return {loading: false};},methods: {...mapActions('user', ['login']),async handleLogin() {this.loading = true;try {const result = await this.login();if (result) {uni.showToast({title: '登录成功',icon: 'success'});// 登录成功后跳转setTimeout(() => {const redirectUrl = uni.getStorageSync('redirectUrl') || '/pages/index/index';uni.reLaunch({url: redirectUrl});uni.removeStorageSync('redirectUrl');}, 1500);}} catch (error) {console.error('登录操作失败', error);} finally {this.loading = false;}}}
};
</script><style>
.login-container {display: flex;flex-direction: column;align-items: center;justify-content: center;padding: 60rpx;height: 100vh;background-color: #f8f8f8;
}.logo {width: 200rpx;height: 200rpx;margin-bottom: 40rpx;
}.welcome {font-size: 36rpx;font-weight: bold;margin-bottom: 80rpx;color: #333;
}.login-btn {width: 80%;height: 88rpx;line-height: 88rpx;border-radius: 44rpx;font-size: 32rpx;background-color: #07c160;
}.tips {margin-top: 40rpx;font-size: 28rpx;color: #999;
}
</style>

登录流程最佳实践

  1. 静默登录:在用户无感知的情况下完成登录流程,提升用户体验。

  2. 登录状态检查:在应用启动和页面切换时检查登录状态,确保用户处于登录状态。

  3. 错误处理:提供友好的错误提示,引导用户成功完成登录。

  4. 登录重试:在登录失败时提供重试机制。

  5. 登录过期处理:及时处理登录过期情况,引导用户重新登录。

  6. 登录态持久化:使用适当的存储方式保存登录态,确保用户下次打开应用时能够保持登录状态。

  7. 登录态安全:不在前端存储敏感信息,设置合理的 token 过期时间。

总结

作为前端开发者,实现微信小程序登录流程需要关注以下关键点:

  1. 正确调用 uni.login() 获取登录凭证
  2. 将登录凭证发送到业务服务器换取登录态
  3. 安全地保存和管理登录态
  4. 在网络请求中使用登录态
  5. 处理登录过期和未授权情况
  6. 优化用户登录体验

通过本文介绍的方法和最佳实践,你应该能够在 uni-app 项目中实现一个完整、安全、用户友好的微信小程序登录流程。

希望这篇文章对你实现微信小程序登录功能有所帮助!

相关文章:

uni-app微信小程序登录流程详解

文章目录 uni-app微信小程序登录流程实战详解微信小程序登录流程概述1. 获取登录凭证&#xff08;code&#xff09;2. 发送登录请求3. 保存登录态4. 登录状态管理5. 应用登录状态请求拦截器中添加 token自动登录页面路由守卫 使用 Vuex 集中管理登录状态登录组件示例登录流程最…...

【C++游戏引擎开发】第34篇:C++实现反射

一、反射系统概述 1.1 反射的核心概念 1.1.1 运行时自省能力 反射允许程序在运行时动态获取和操作自身的类型信息。这种能力突破了静态类型语言的限制,使得开发者可以: 检查对象类型及其成员结构动态创建未在编译期确定的类型实例实现类型无关的通用操作接口1.1.2 元数据驱…...

C# 的异步任务中, 如何暂停, 继续,停止任务

namespace taskTest {using System;using System.Threading;using System.Threading.Tasks;public class MyService{private Task? workTask;private readonly SemaphoreSlim semaphore new SemaphoreSlim(0, 1); // 初始为 0&#xff0c;Start() 启动时手动放行private read…...

langchain4j中使用milvus向量数据库做RAG增加索引

安装milvus向量数据库 官方网址 https://milvus.io/zh 使用docker安装milvus mkdir -p /data/docker/milvus cd /data/docker/milvus wget https://raw.githubusercontent.com/milvus-io/milvus/master/scripts/standalone_embed.sh#在docker中启动milvus sh standalone_emb…...

MySQL SQL Mode及其说明

以下是MySQL中所有支持的SQL Mode及其说明&#xff0c;综合了多个来源的信息并进行了分类整理&#xff1a; 一、严格模式相关 STRICT_TRANS_TABLES 对事务型存储引擎&#xff08;如InnoDB&#xff09;启用严格数据校验。若插入非法值&#xff08;如类型不符、超出范围等&#…...

Web前端最新导航

前言 本文列出了很多与前端有关的常见网站、博客、工具等&#xff0c;整体来看比较权威。有些东西已经过时了&#xff0c;我就不列出来了。学是一方面&#xff0c;也是最主要的方面&#xff1b;但还有一个作用&#xff0c;比如&#xff0c;“这个前端框架你都不知道啊”、“这个…...

2025年AI工程师认证深度解析:AAIA认证体系全景指南与实战策略

一、IAAAI认证体系演进与价值定位 1.1 国际人工智能认证发展现状 全球人工智能认证市场呈现显著分化态势。据Gartner 2025Q1报告显示&#xff0c;北美市场以IEEE/ACM双认证体系为主导&#xff08;市占率38%&#xff09;&#xff0c;欧盟区推行AI Act合规认证&#xff08;强制…...

CentOS 和 RHEL

CentOS 和 RHEL&#xff08;Red Hat Enterprise Linux&#xff09;关系非常紧密&#xff0c;简而言之&#xff1a; CentOS 最初是 RHEL 的免费、开源克隆版&#xff0c;几乎与 RHEL 二进制兼容。 CentOS 原是 RHEL 的“免费双胞胎”&#xff0c;但已被放弃&#xff0c;现在推荐…...

flask开启https服务支持

目录 一、背景 二、开启https支持 三、自签名 1、安装openssl 2、验证安装 3、自签名 四、编写代码 五、访问https接口 一、背景 最近在做自动化业务&#xff0c;需要兼容现在主流的框架开发的前端页面&#xff0c;于是到github找到了几个项目&#xff0c;clone下来项目并…...

统计服务器CPU、内存、磁盘、网络IO、队列、数据库占用空间等等信息

文章目录 一、背景二、说明三、页面四、代码 前端 MonitorServiceProcessPage.vueMonitorServiceProcessTable.vueMonitorServiceProcessTableButton.vueaddMonitorTask.vueproductOperation.vueshowMonitorTask.vueMonitorSystemLog.vueMonitorTask.vueMonitorTaskLog.vueReal…...

【SGL】Scatter-Gather List内存传输技术

文章目录 1. What is SGL&#xff1f;2. sgl内存传输的原理2.1 核心思想2.2 sgl数据结构2.3 摘链和挂链 3. 零拷贝技术3.1 问题背景3.2 零拷贝的核心思想及实现方式 4. sgl在存储行业的应用 1. What is SGL&#xff1f; sgl&#xff08;Scatter-Gather List&#xff09;内存传…...

-MAC桢-

MAC桢和IP的关系&#xff1a; 主机A想跨网络和B通信需要IP地址进行路由选择&#xff0c;但一个局域网&#xff0c;比如路由器进行路由选择之前&#xff0c;首先要将数据包发送给路由器B&#xff0c;也就是局域网通信也就是同一个网段的主机进行通信&#xff0c;所以必须通过mac…...

安装:Kali2025+Docker

安装:Kali2025Docker Kali2025安装 直接官网下载WMware版本 https://www.kali.org/get-kali/#kali-virtual-machines 直接打开运行 初始用户密码 kali/kali sudo -i 命令切换到root 更换镜像 切换到其他可用的 Kali Linux 镜像源可能会解决问题,可以使用国内的镜像源&…...

Linux云计算训练营笔记day04[Rocky Linux中的命令:mv、cp、grep(^$)、tar、重定向>和>>]

mv 移动(剪切) 源数据会消失 格式: mv 源文件 目标路径 touch /opt/a.txt 创建文件 mv /opt/a.txt /root 移动文件&#xff0c;没有改名 mkdir gongli 创建目录 mv gongli /opt/ 移动目录&#xff0c;没有改名 mv /opt/gongli tedu 移动目录&#xff0c;改名了 …...

AbMole Olaparib:打破常规,用PARP抑制重塑肿瘤研究

在当今的生物医学研究领域&#xff0c;Olaparib&#xff08;AZD2281&#xff0c;AbMole&#xff0c;M1664&#xff09;作为一种重要的PARP&#xff08;聚腺苷二磷酸核糖聚合酶&#xff09;抑制剂&#xff0c;受到了广泛关注。Olaparib可干扰 DNA 单链断裂的修复&#xff0c;从而…...

RPC、gRPC和HTTP的区别

RPC 只是一种屏蔽远程过程调用的设计&#xff0c;它与HTTP不是对立的&#xff0c;两者不是一个层面的概念。 RPC底层通信可以使用TCP实现&#xff08;如Thrift&#xff09;&#xff0c;也可以使用HTTP实现&#xff08;如gRPC&#xff09;&#xff0c;其本身并无限制。 1. 概念…...

Windows重置网络,刷新缓存

同时按键盘上的【Windows】键和【S】键&#xff0c;弹出搜索框&#xff0c;输入 命令提示符 在“最佳匹配”下的【命令提示符】上右键&#xff0c;点击【以管理员身份运行】 1弹出一个窗口&#xff0c;在光标闪烁的位置&#xff0c;直接输入【netsh winsock reset】&#xff0…...

Ref是什么

在 React 中&#xff0c;ref 是一种用于访问 DOM 元素或组件实例的机制。它允许你在组件中直接操作 DOM 元素&#xff0c;或者访问子组件的实例。ref 的使用场景非常广泛&#xff0c;包括表单操作、焦点控制、动画等。以下是关于 ref 的详细讲解以及在项目中的常见使用场景。 …...

OpenHarmony平台驱动开发(十),MMC

OpenHarmony平台驱动开发&#xff08;十&#xff09; MMC 概述 功能简介 MMC&#xff08;MultiMedia Card&#xff09;即多媒体卡&#xff0c;是一种用于固态非易失性存储的小体积大容量的快闪存储卡。 MMC后续泛指一个接口协定&#xff08;一种卡式&#xff09;&#xff0…...

解决IDEA无法运行git的问题

之前git一直没有问题&#xff0c;今天打开就提示我安装git&#xff0c;自然用git去提交新项目也会遇到问题。 我出现问题的原因是&#xff1a;git路径缺失 文件->设置->git 发现git的路径为空&#xff0c;按照实际位置填写即可...

HTTP 响应状态码总结

一、引言 HTTP 响应状态码是超文本传输协议&#xff08;HTTP&#xff09;中服务器对客户端&#xff08;通常是 Web 浏览器&#xff09;请求的响应指示。这些状态码是三位数字代码&#xff0c;用于告知客户端请求的结果&#xff0c;包括请求是否成功。响应被分为五个类别&#…...

Java求职面试:Spring Boot与微服务的幽默探讨

Java求职者面试&#xff1a;技术与幽默的碰撞 场景概述 在某互联网大厂的面试现场&#xff0c;面试官严肃认真&#xff0c;程序员则是一个搞笑的水货角色。面试者名叫张伟&#xff0c;年龄28岁&#xff0c;硕士学历&#xff0c;拥有5年的Java开发经验。以下是面试的详细过程。…...

lua脚本+Redission实现分布式锁

实现分布式锁最简单的一种方式&#xff1a;基于Redis 不论是本地锁还是分布式锁&#xff0c;核心都在于“互斥”。 在 Redis 中&#xff0c; SETNX 命令是可以帮助我们实现互斥。SETNX 即 set if not exists (对应 Java 中的 setIfAbsent 方法)&#xff0c;如果 key 不存在的…...

JVM之jcmd命令详解

jcmd 是 Oracle JDK&#xff08;Java Development Kit&#xff09;自 JDK 7 起引入的一个强大的诊断工具&#xff0c;用于与正在运行的 JVM&#xff08;Java Virtual Machine&#xff09;实例进行交互。它允许用户执行各种诊断命令&#xff0c;比如线程堆栈分析、堆转储、GC 信…...

Go语言:json 作用和语法

在 Go 语言中&#xff0c;JSON 字段&#xff08;也称为 JSON Tag&#xff09;是附加在结构体字段上的元数据&#xff0c;用于控制该字段在 JSON 编码&#xff08;序列化&#xff09;和解码&#xff08;反序列化&#xff09; 时的行为。它的语法是&#xff1a; type StructName…...

Hive HA配置高可用

Hive的高可用性(HA)通过消除关键组件的单点故障来实现,确保系统在部分故障时仍能正常运行。其基本原理涉及以下核心组件和策略: ‌1. Hive Metastore 的高可用‌ ‌ 多实例部署‌:部署多个Metastore服务实例,每个实例连接到共享的后端数据库(如MySQL、PostgreSQ…...

Ubuntu 第11章 网络管理_常用的网络配置命令

为了管理网络&#xff0c;Linux提供了许多非常有用的网络管理命令。利用这些命令&#xff0c;一方面可以有效地管理网络&#xff0c;另一方面出现网络故障时&#xff0c;可以快速进行诊断。本节将对Ubuntu提供的网络管理命令进行介绍。 11.2.1 ifconfig命令 关于ifconfig命令&…...

【Qt】Qt 构建系统详解:qmake 入门到项目实战

Qt 构建系统详解&#xff1a;qmake 入门到项目实战 本文将系统介绍 Qt 构建工具 qmake 的用法&#xff0c;并通过一个完整的项目结构示例&#xff0c;帮助你掌握 .pro 文件编写、子项目管理、模块依赖等核心技能。 &#x1f9ed; 一、什么是 qmake&#xff1f; qmake 是 Qt 提…...

Python实例题:pygame开发打飞机游戏

目录 Python实例题 题目 pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本 代码解释 初始化部分&#xff1a; 游戏主循环&#xff1a; 退出部分&#xff1a; 运行思路 注意事项 Python实例题 题目 pygame开发打飞机游戏 pygame-aircraft-game使用 Pygame 开发…...

《Zabbix Proxy分布式监控实战:从安装到配置全解析》

注意&#xff1a;实验所需的zabbix服务器的搭建可参考博客 zabbix 的docker安装_docker安装zabbix-CSDN博客 1.1 实验介绍 1.1.1 实验目的 本实验旨在搭建一个基于Zabbix的监控系统&#xff0c;通过安装和配置Zabbix Proxy、MySQL数据库以及Zabbix Agent&#xff0c;实现分…...