登录功能开发
一、整体架构设计
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))
})
})
}
十、总结
本文档详细描述了登录功能的开发思路和技术实现方案,包括:
- 完整的登录流程设计
- 安全机制的实现
- 状态管理方案
- APP端开发建议
- 性能优化策略
在实际开发中,需要根据具体需求和场景进行适当调整和优化。特别是在开发APP端时,需要充分考虑移动端的特点和用户体验。