【慧游鲁博】【8】前后端用户信息管理:用户基本信息在小程序端的持久化与随时获取

文章目录

本次更新

在小程序端获取并保存当前用户的详细信息,支持后续对用户信息的使用。

整体流程概述

整个用户信息管理流程可以分为以下几个关键步骤:

  1. 用户登录:前端发送登录请求,后端验证并返回token
  2. 信息存储:前端存储token并获取用户详细信息
  3. 后续请求:每次请求携带token进行身份验证
  4. 信息获取:通过存储的token获取用户信息

下面我将详细分析每个环节的实现。

1. 用户登录流程

前端登录处理 (login.vue)

在前端的handleLogin方法中,主要完成了以下工作:

javascript 复制代码
async handleLogin() {
  // 验证输入...
  
  // 发送登录请求
  const res = await post('/user/login', {
    username: this.loginForm.username,
    password: this.loginForm.password
  })

  // 存储token
  const memberStore = useMemberStore()
  memberStore.setToken(res)
  uni.setStorageSync('token', res)

  // 获取用户详细信息并存储
  const userInfoRes = await get('/user/getUserInfo')
  memberStore.setUserInfo(userInfoRes)
  
  // 跳转逻辑...
}
  1. 前端发送登录请求到/user/login接口,携带用户名和密码
  2. 登录成功后,将返回的token存储到Pinia状态管理和uni-app的本地存储中
  3. 随后立即调用/user/getUserInfo获取用户详细信息并存储

后端登录处理 (AuthServiceImpl.java)

后端登录逻辑主要位于AuthServiceImpl类中:

java 复制代码
public Result<String> login(UserLoginDTO loginDTO) {
    // 查询用户
    User user = this.getOne(new LambdaQueryWrapper<User>()
            .eq(User::getUsername, loginDTO.getUsername()));

    // 验证用户存在性和密码
    if (user == null) return Result.fail(ErrorCode.USER_NOT_EXIST);
    if (!Md5Util.getMD5String(loginDTO.getPassword()).equals(user.getPassword())) {
        return Result.fail(ErrorCode.PASSWORD_ERROR);
    }

    // 生成JWT token
    Map<String, Object> claims = new HashMap<>();
    claims.put("id", user.getId());
    claims.put("username", user.getUsername());
    String token = JwtUtil.genToken(claims);

    // 将token存入Redis
    redisService.set(token, token, 1, TimeUnit.HOURS);
    
    return Result.success(token);
}
  1. 验证用户名和密码
  2. 生成包含用户ID和用户名的JWT token
  3. 将token存入Redis,设置1小时有效期
  4. 返回token给前端

2. 用户信息存储机制

前端状态管理 (member.js)

前端使用Pinia进行状态管理,关键代码如下:

javascript 复制代码
const profile = ref({
  token: '',       // 登录令牌
  userInfo: null   // 用户详细信息
})

// 设置token
const setToken = (token) => {
  profile.value.token = token || ''
}

// 设置用户信息
const setUserInfo = (userInfo) => {
  profile.value.userInfo = userInfo || null
}

// 持久化配置
{
  persist: {
    storage: {
      getItem(key) {
        return uni.getStorageSync(key)
      },
      setItem(key, value) {
        uni.setStorageSync(key, value)
      },
    },
  }
}
  1. 使用profile对象存储token和用户信息
  2. 提供setTokensetUserInfo方法更新状态
  3. 配置了持久化存储,将状态同步到uni-app的本地存储中

这种设计实现了:

  • 内存中快速访问用户信息
  • 页面刷新后仍能保持登录状态
  • 统一的用户信息管理接口

3. 后续请求的身份验证

登录拦截器 (LoginInterceptor.java)

后端通过拦截器验证每个请求的身份:

java 复制代码
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    // 从请求头获取token
    String token = request.getHeader("Authorization");
    
    try {
        // 从Redis验证token有效性
        String redisToken = operations.get(token);
        if (redisToken==null) throw new RuntimeException();
        
        // 解析token获取用户信息
        Map<String, Object> claims = JwtUtil.parseToken(token);
        
        // 存储到ThreadLocal中供后续使用
        ThreadLocalUtil.set(claims);
        
        return true;
    } catch (Exception e) {
        response.setStatus(401);
        return true;
    }
}
  1. Authorization请求头获取token
  2. 检查Redis中是否存在该token(确保未过期)
  3. 解析token获取用户信息并存入ThreadLocal
  4. 验证失败返回401状态码

前端请求携带token

前端在member.js中提供了获取token的方法:

javascript 复制代码
// 获取token
const getToken = () => {
  return profile.value.token
}

在发起API请求时,前端应该从store中获取token并添加到请求头中:

javascript 复制代码
const token = memberStore.getToken()
const res = await request({
  url: '/api/protected',
  headers: {
    'Authorization': token
  }
})

4. 获取用户信息

获取用户信息接口 (UserController.java)

后端提供获取用户信息的接口:

java 复制代码
@GetMapping("/getUserInfo")
public Result<UserVO> getUserInfo() {
    return userService.getUserInfo();
}

前端获取和存储用户信息

前端在登录成功后立即获取用户信息:

javascript 复制代码
// 获取用户详细信息并存储
const userInfoRes = await get('/user/getUserInfo')
memberStore.setUserInfo(userInfoRes)

之后可以通过store随时获取(我亲爱的队友们,请你们关注这里):

javascript 复制代码
const memberStore = useMemberStore()
const userInfo = memberStore.getUserInfo()

安全设计考虑

  1. Token有效期:后端设置token 1小时有效期(Redis中)
  2. 密码安全:后端存储密码的MD5哈希值而非明文
  3. 信息最小化:Token中只包含必要信息(id和username)
  4. HTTPS传输:虽然代码中未体现,但生产环境应使用HTTPS

综上所述

这套用户信息管理机制实现了:

  1. 安全的登录流程:验证用户名密码后生成有时效性的token
  2. 前后端状态同步:前端存储token和用户信息,后端验证每个请求
  3. 持久化存储:即使刷新页面也能保持登录状态
  4. 便捷的信息获取:通过store可以随时获取当前用户信息
相关推荐
徐礼昭|商派软件市场负责人17 小时前
从“多、老、旧”到“4i焕新”:品牌官方商城(小程序/官网/APP···)的范式跃迁与增长再想象
小程序·商城系统·零售
胡西风_foxww1 天前
微信小程序转Vue2组件智能提示词
微信小程序·小程序·提示词·智能体·vue2组件
飏旎1 天前
对于前端闭包的详细理解
前端·状态模式
七七软件开发1 天前
一对一交友小程序 / APP 系统架构分析
java·python·小程序·系统架构·php
2501_916007471 天前
iPhone查看App日志和系统崩溃日志的完整实用指南
android·ios·小程序·https·uni-app·iphone·webview
说私域1 天前
基于开源链动2+1模式AI智能名片S2B2C商城小程序的私域流量拉新策略研究
人工智能·小程序·开源
曾经的三心草1 天前
微服务的编程测评系统9-竞赛新增-竞赛编辑
微服务·架构·状态模式
2501_915918411 天前
iOS 抓不到包怎么办?全流程排查思路与替代引导
android·ios·小程序·https·uni-app·iphone·webview
七七软件开发1 天前
团购商城 app 系统架构分析
java·python·小程序·eclipse·系统架构·php
七七软件开发1 天前
打车小程序 app 系统架构分析
java·python·小程序·系统架构·交友