登录功能开发

一、整体架构设计

1.1 技术栈

  • 前端框架:Vue 3 + Element Plus
  • 状态管理:Vuex
  • 路由管理:Vue Router
  • HTTP请求:Axios
  • 数据加密:crypto-js
  • Token管理:JWT

1.2 核心功能模块

登录系统
├── 用户认证
│   ├── 账号密码登录
│   ├── 手机验证码登录
│   └── 记住密码
├── 权限管理
│   ├── 角色权限控制
│   ├── 菜单权限
│   └── 按钮权限
└── 安全机制
    ├── Token验证
    ├── 密码加密
    └── 登录状态维护

二、数据结构设计

2.1 登录请求数据结构

// 账号密码登录
const loginData = {
  username: String,    // 用户名
  password: String,    // 密码(加密后)
  rememberMe: Boolean, // 记住密码
  captcha: String      // 验证码(如果需要)
}

// 手机验证码登录
const phoneLoginData = {
  phone: String,       // 手机号
  verifyCode: String,  // 验证码
  rememberMe: Boolean  // 记住登录
}

2.2 用户信息数据结构

const userInfo = {
  userId: String,      // 用户ID
  username: String,    // 用户名
  realName: String,    // 真实姓名
  avatar: String,      // 头像
  phone: String,       // 手机号
  email: String,       // 邮箱
  role: String,        // 角色(部门主管/普通用户)
  permissions: Array,  // 权限列表
  token: String        // 访问令牌
}

三、API接口设计

3.1 基础接口

const authApis = {
  login: '/auth/login',                // 账号密码登录
  phoneLogin: '/auth/phone-login',     // 手机号登录
  logout: '/auth/logout',              // 退出登录
  getVerifyCode: '/auth/verify-code',  // 获取验证码
  refreshToken: '/auth/refresh-token', // 刷新token
  getUserInfo: '/auth/user-info'       // 获取用户信息
}

3.2 接口请求示例

// 登录请求
const login = async (loginData) => {
  try {
    const response = await request.post('/auth/login', {
      username: loginData.username,
      password: encrypt(loginData.password),
      rememberMe: loginData.rememberMe
    })
    return handleLoginSuccess(response.data)
  } catch (error) {
    handleLoginError(error)
  }
}

四、状态管理设计

4.1 Vuex Store结构

const store = {
  state: {
    token: null,
    userInfo: null,
    permissions: [],
    rememberMe: false
  },
  mutations: {
    SET_TOKEN(state, token),
    SET_USER_INFO(state, userInfo),
    SET_PERMISSIONS(state, permissions),
    SET_REMEMBER_ME(state, rememberMe)
  },
  actions: {
    async login({ commit }, loginData),
    async logout({ commit }),
    async getUserInfo({ commit }),
    async refreshToken({ commit })
  }
}

4.2 持久化存储

// localStorage存储
const Storage = {
  setToken(token) {
    localStorage.setItem('token', token)
  },
  getToken() {
    return localStorage.getItem('token')
  },
  setUserInfo(info) {
    localStorage.setItem('userInfo', JSON.stringify(info))
  },
  getUserInfo() {
    return JSON.parse(localStorage.getItem('userInfo'))
  },
  clear() {
    localStorage.removeItem('token')
    localStorage.removeItem('userInfo')
  }
}

五、安全机制

5.1 密码加密

import CryptoJS from 'crypto-js'

const encrypt = (password) => {
  return CryptoJS.MD5(password).toString()
}

5.2 Token管理

// 请求拦截器
request.interceptors.request.use(config => {
  const token = store.state.token
  if (token) {
    config.headers['Authorization'] = `Bearer ${token}`
  }
  return config
})

// 响应拦截器
request.interceptors.response.use(
  response => response,
  error => {
    if (error.response.status === 401) {
      // token过期,尝试刷新
      return refreshTokenAndRetry(error)
    }
    return Promise.reject(error)
  }
)

六、路由守卫

6.1 登录拦截

router.beforeEach(async (to, from, next) => {
  const token = store.state.token
  
  if (to.meta.requiresAuth) {
    if (!token) {
      next('/login')
      return
    }
    
    // 判断是否已获取用户信息
    if (!store.state.userInfo) {
      try {
        await store.dispatch('getUserInfo')
      } catch (error) {
        next('/login')
        return
      }
    }
    
    // 判断权限
    if (to.meta.roles && !hasPermission(store.state.userInfo.role, to.meta.roles)) {
      next('/403')
      return
    }
  }
  
  next()
})

七、APP端开发建议

7.1 技术选型

- 状态管理:Redux/MobX
- 存储方案:AsyncStorage/SQLite
- 加密方案:react-native-crypto
- 生物认证:指纹/面部识别

7.2 功能扩展

1. 多重认证

  • 生物识别登录
  • 手势密码
  • 短信验证码
  • 邮箱验证码

2. 安全增强

  • 设备指纹采集
  • 异地登录提醒
  • 登录日志记录
  • 自动锁屏

3. 离线功能

  • Token本地加密存储
  • 自动登录
  • 离线状态判断
  • 数据同步策略

八、开发技巧与最佳实践

8.1 错误处理

const handleLoginError = (error) => {
  if (error.response) {
    switch (error.response.status) {
      case 400:
        ElMessage.error('用户名或密码错误')
        break
      case 401:
        ElMessage.error('登录已过期,请重新登录')
        break
      case 429:
        ElMessage.error('登录尝试次数过多,请稍后再试')
        break
      default:
        ElMessage.error('登录失败,请稍后重试')
    }
  }
}

8.2 表单验证

const loginRules = {
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }
  ],
  password: [
    { required: true, message: '请输入密码', trigger: 'blur' },
    { min: 6, max: 20, message: '长度在 6 到 20 个字符', trigger: 'blur' }
  ]
}

九、性能优化

9.1 登录状态检查优化

// 使用本地存储加快登录状态检查
const checkLoginStatus = () => {
  const token = Storage.getToken()
  const userInfo = Storage.getUserInfo()
  
  if (token && userInfo) {
    store.commit('SET_TOKEN', token)
    store.commit('SET_USER_INFO', userInfo)
    return true
  }
  return false
}

9.2 Token刷新优化

// 使用刷新令牌队列,避免重复请求
let isRefreshing = false
let requests = []

const refreshTokenAndRetry = async (error) => {
  if (!isRefreshing) {
    isRefreshing = true
    try {
      const newToken = await store.dispatch('refreshToken')
      requests.forEach(cb => cb(newToken))
      return request(error.config)
    } catch (err) {
      store.dispatch('logout')
      return Promise.reject(err)
    } finally {
      isRefreshing = false
      requests = []
    }
  }
  
  return new Promise(resolve => {
    requests.push(token => {
      error.config.headers['Authorization'] = `Bearer ${token}`
      resolve(request(error.config))
    })
  })
}

十、总结

本文档详细描述了登录功能的开发思路和技术实现方案,包括:

  1. 完整的登录流程设计
  2. 安全机制的实现
  3. 状态管理方案
  4. APP端开发建议
  5. 性能优化策略

在实际开发中,需要根据具体需求和场景进行适当调整和优化。特别是在开发APP端时,需要充分考虑移动端的特点和用户体验。

posted on 2025-04-24 19:48  -MARIO  阅读(7)  评论(0)    收藏  举报