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 项目中实现一个完整、安全、用户友好的微信小程序登录流程。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/80885.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

GUC并发编程和SpringCloud,二者之间的关系

一.提问 我认为&#xff0c;Java开发中&#xff0c;如果项目的每一个小模块需要不同人员并行开发时&#xff0c;就需要使用SpringCloud&#xff1b;如果要解决系统用户激增&#xff0c;就是用GUC并发编程。 这个说法对么&#xff1f; 二.解答 你的理解部分正确&#xff0c;但不…

在 Vue 3 中使用 canvas-confetti 插件

&#x1f389; 在 Vue 3 中使用 canvas-confetti 插件 canvas-confetti 是一个轻量、无依赖的 JavaScript 动画库&#xff0c;用于在网页上展示彩带、庆祝动画。非常适合用于抽奖、支付成功、活动庆祝等场景。 本教程将指导你如何在 Vue 3 项目中集成并使用该插件。 &#x1…

深入解析Spring Boot项目目录结构:从新手到规范实践

一、标准项目结构全景图 典型的Spring Boot项目&#xff08;Maven构建&#xff09;目录结构如下&#xff1a; my-spring-project/ ├── src/ │ ├── main/ │ │ ├── java/ # 核心代码 │ │ │ └── com/ │ │ │ └── exa…

【C语言】宏经典练习题,交换奇偶位

交换奇偶位 写一个宏&#xff0c;可以将一个整数的二进制位的奇数位和偶数位交换。 #define Swap(x) x(((x&0x55555555)<<1)((x&0xaaaaaaaa)>>1)) int main() {int a 10;Swap(a);printf("%d\n", a);return 0; } 写宏的思路&#xff1a; 假设…

VSCode-插件:codegeex:ai coding assistant / 清华智普 AI 插件

一、官网 https://codegeex.cn/ 二、vscode 安装插件 点击安装即可&#xff0c;无需复杂操作&#xff0c;国内软件&#xff0c;无需科学上网&#xff0c;非常友好 三、智能注释 输入 // 或者 空格---后边自动出现注释信息&#xff0c;&#xff0c;按下 Tab 键&#xff0c;进…

FFmpeg 与 C++ 构建音视频处理全链路实战(三)—— FFmpeg 内存模型

经过前面文章的 FFmpeg 编程实践&#xff0c;相信你已经对AVPacket和AVFrame这两个核心结构体不再陌生。当我们编写代码时&#xff0c;频繁调用unref系列 API 释放内存的操作&#xff0c;或许让你心生疑惑&#xff1a;这些函数究竟是如何实现内存释放的&#xff1f;又该在何时准…

c 中的哈希表

哈希是一种可以接受各种类型、大小的输入&#xff0c;输出一个固定长度整数的过程。你可以将哈希理解成一种特殊的映射&#xff0c;哈希映射&#xff0c;将一个理论无限的集合A映射到有限整数集合B上。 哈希函数&#xff1a;哈希函数是哈希过程的核心&#xff0c;它决定了哈希映…

【一次成功!】Ubuntu22.04安装cartographer

之前在ubuntu20.04上成功安装cartographer&#xff0c;但是翻遍全网都没找到官方的22.04安装教程&#xff0c;然后找到小鱼的&#xff0c;试了一下&#xff0c;一次成功&#xff0c;连接如下&#xff1a; gd2l-ros2/docs/humble/chapt10/get_started/2.Carto介绍及安装.md at …

【WPF】Opacity 属性的使用

在WPF&#xff08;Windows Presentation Foundation&#xff09;中&#xff0c;Opacity 属性是定义一个元素透明度的属性&#xff0c;其值范围是从 0.0&#xff08;完全透明&#xff09;到 1.0&#xff08;完全不透明&#xff09;。由于 Opacity 是在 UIElement 类中定义的&…

8天Python从入门到精通【itheima】-6~10

目录 7节-开发出第一个Python程序: 1.在cmd窗口写下第一个最简单的程序:Hello World!!! 9节: 1.如何卸载python: 2.报错:不是可运行的程序 ​编辑 3.报错:无法初始化设备PRN: 4.报错:语法错误——非法的字符 10节-python解释器: 1.python解释器的原理: 2.解…

Mac 3大好用的复制粘贴管理工具对比

剪贴板管理器是查看复制粘贴历史记录的工具&#xff0c;几乎是每个苹果电脑用户必备工具。市面上的工具很多&#xff0c;我结合了功能丰富、设计简洁、交互便利整理了目前3款头部剪贴板应用 Paste、PasteNow、PasteMe。 Paste 优势&#xff1a;老牌剪切板应用&#xff0c;功能…

2025年全国青少年信息素养大赛初赛模拟测试网站崩了的原因及应对比赛流程

2025年全国青少年信息素养大赛初赛模拟测试昨天开始&#xff0c;由于同一时间涌入太多的人&#xff0c;导致网站的服务器奔了&#xff0c;出现了各种状况&#xff0c;导致很多人没有模拟上&#xff0c;大家今天可以刷新或者提前打开网页。 有的是一直“转圈圈”&#xff0c;有的…

02 | 大模型微调 | 从0学习到实战微调 | 从数学概率到千亿参数大模型

一、导读 作为非AI专业技术开发者&#xff08;我是小小爬虫开发工程师&#x1f60b;&#xff09; 本系列文章将围绕《大模型微调》进行学习&#xff08;也是我个人学习的笔记&#xff0c;所以会持续更新&#xff09;&#xff0c;最后以上手实操模型微调的目的。 &#xff08;…

十四、继承与组合(Inheritance Composition)

十四、继承与组合&#xff08;Inheritance & Composition&#xff09; 引言 C最引人注目的特性之一是代码复用。组合&#xff1a;在新类中创建已有类的对象。继承&#xff1a;将新类作为已有类的一个类型来创建。 14.1 组合的语法 Useful.h //C14:Useful.h #ifndef US…

2025年5月-信息系统项目管理师高级-软考高项一般计算题

决策树和期望货币值 加权算法 自制和外购分析 沟通渠道 三点估算PERT 当其他条件一样时&#xff0c;npv越大越好

OpenJDK 17 中线程启动的完整流程用C++ 源码详解

1. 线程创建入口&#xff08;JNI 层&#xff09; 当 Java 层调用 Thread.start() 时&#xff0c;JVM 通过 JNI 进入 JVM_StartThread 函数&#xff1a; JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread))// 1. 检查线程状态&#xff0c;防止重复启动if (java_…

Spring MVC参数传递

本内容采用最新SpringBoot3框架版本,视频观看地址:B站视频播放 1. Postman基础 Postman是一个接口测试工具,Postman相当于一个客户端,可以模拟用户发起的各类HTTP请求,将请求数据发送至服务端,获取对应的响应结果。 2. Spring MVC相关注解 3. Spring MVC参数传递 Spri…

Python面向对象编程(OOP)深度解析:从封装到继承的多维度实践

引言 面向对象编程(Object-Oriented Programming, OOP)是Python开发中的核心范式&#xff0c;其三大特性——​​封装、继承、多态​​——为构建模块化、可维护的代码提供了坚实基础。本文将通过代码实例与理论结合的方式&#xff0c;系统解析Python OOP的实现机制与高级特性…

0.66kV0.69kV接地电阻柜常规配置单

0.66kV/0.69kV接地电阻柜是变压器中性点接地电阻柜中的特殊存在&#xff0c;主要应用于低压柴油发电机组220V、火力发电厂380V、煤炭企业660V/690V等电力系统或电力用户1000V的低压系统中。 我们来看看0.66kV0.69kV接地电阻柜配置单&#xff1a; 配置特点如下&#xff1a; 1…

矩阵短剧系统:如何用1个后台管理100+小程序?深度解析多端绑定技术

短剧行业效率革命&#xff01;一套系统实现多平台内容分发、数据统管与流量聚合 在短剧行业爆发式增长的今天&#xff0c;内容方和运营者面临两大核心痛点&#xff1a;多平台运营成本高与流量分散难聚合。传统模式下&#xff0c;每个小程序需独立开发后台&#xff0c;导致人力…