用户注册和登录流程
目录
概述
本文档详细说明系统中用户注册和登录的完整流程,包括前端交互、后端处理、数据存储等各个环节。
用户注册流程
1. 注册方式
系统支持以下注册方式:
- 账号密码注册:使用用户名/手机号/邮箱 + 密码注册
- 手机号注册:手机号 + 短信验证码注册
- 第三方登录注册:微信、QQ、支付宝等第三方平台授权注册
2. 账号密码注册流程
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 前端页面 │ --> │ 表单验证 │ --> │ 提交注册 │ --> │ 后端处理 │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│
v
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 注册成功 │ <-- │ 返回结果 │ <-- │ 数据存储 │ <-- │ 业务验证 │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘详细步骤:
用户填写注册信息
- 用户名(必填):4-20位字符,支持字母、数字、下划线
- 密码(必填):6-20位字符,必须包含字母和数字
- 确认密码(必填):与密码一致
- 手机号(选填):用于找回密码和接收通知
- 验证码(必填):图形验证码防刷
前端表单验证
- 验证字段格式是否符合要求
- 验证两次密码是否一致
- 验证图形验证码是否正确
提交注册请求
javascript// 请求示例 POST /api/auth/register { "username": "testuser", "password": "encrypted_password", "password_confirm": "encrypted_password", "mobile": "13800138000", "captcha": "a1b2", "captcha_key": "uuid_key" }后端处理流程
- 接收请求参数
- 验证图形验证码
- 验证用户名是否已存在
- 验证手机号是否已注册
- 密码加密存储(使用bcrypt)
- 创建用户记录
- 初始化用户相关数据
返回注册结果
- 成功:返回用户信息及登录凭证
- 失败:返回错误信息
3. 手机号注册流程
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 输入手机号 │ --> │ 发送验证码 │ --> │ 输入验证码 │ --> │ 提交注册 │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘详细步骤:
输入手机号
- 验证手机号格式
- 检查手机号是否已注册
发送短信验证码
- 生成6位数字验证码
- 调用短信服务发送
- 验证码有效期5分钟
- 同一手机号60秒内不能重复发送
输入验证码和密码
- 用户输入收到的短信验证码
- 设置登录密码
提交注册
javascript// 请求示例 POST /api/auth/register/mobile { "mobile": "13800138000", "sms_code": "123456", "password": "encrypted_password" }
用户登录流程
1. 登录方式
- 账号密码登录:用户名/手机号/邮箱 + 密码
- 手机号快捷登录:手机号 + 短信验证码
- 第三方登录:微信、QQ、支付宝等OAuth授权
2. 账号密码登录流程
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 输入账号 │ --> │ 输入密码 │ --> │ 提交登录 │ --> │ 后端验证 │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘
│
v
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 登录成功 │ <-- │ 返回Token │ <-- │ 生成凭证 │ <-- │ 验证成功 │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘详细步骤:
用户输入账号和密码
- 账号:用户名/手机号/邮箱
- 密码:用户设置的登录密码
- 图形验证码(可选,错误多次后必填)
前端提交登录请求
javascript// 请求示例 POST /api/auth/login { "account": "testuser", "password": "encrypted_password", "captcha": "a1b2", "captcha_key": "uuid_key" }后端验证流程
- 验证图形验证码(如需要)
- 根据账号查询用户信息
- 验证密码是否正确
- 检查账号状态(是否禁用)
- 记录登录日志
生成登录凭证
- 生成JWT Token
- 设置Token过期时间
- 存储登录状态到Redis
返回登录结果
javascript// 成功响应示例 { "code": 200, "message": "登录成功", "data": { "token": "eyJhbGciOiJIUzI1NiIs...", "token_type": "Bearer", "expires_in": 7200, "user_info": { "user_id": 10001, "username": "testuser", "nickname": "测试用户", "avatar": "https://...", "mobile": "13800138000" } } }
3. 手机号快捷登录
javascript
// 请求示例
POST /api/auth/login/mobile
{
"mobile": "13800138000",
"sms_code": "123456"
}流程说明:
- 用户输入手机号
- 发送短信验证码
- 输入验证码提交登录
- 后端验证验证码
- 如手机号未注册,自动创建账号
- 返回登录凭证
密码找回流程
1. 通过手机号找回
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 输入手机号 │ --> │ 验证身份 │ --> │ 设置新密码 │ --> │ 完成找回 │
└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘详细步骤:
输入手机号
- 验证手机号格式
- 检查手机号是否已注册
身份验证
- 发送短信验证码
- 用户输入验证码
- 验证验证码正确性
设置新密码
javascript// 请求示例 POST /api/auth/password/reset { "mobile": "13800138000", "sms_code": "123456", "new_password": "encrypted_password" }完成找回
- 更新用户密码
- 使所有登录态失效
- 返回操作结果
API接口说明
注册相关接口
| 接口地址 | 请求方式 | 功能说明 |
|---|---|---|
| /api/auth/register | POST | 账号密码注册 |
| /api/auth/register/mobile | POST | 手机号注册 |
| /api/auth/captcha | GET | 获取图形验证码 |
| /api/auth/sms/send | POST | 发送短信验证码 |
登录相关接口
| 接口地址 | 请求方式 | 功能说明 |
|---|---|---|
| /api/auth/login | POST | 账号密码登录 |
| /api/auth/login/mobile | POST | 手机号快捷登录 |
| /api/auth/logout | POST | 用户登出 |
| /api/auth/refresh | POST | 刷新Token |
密码相关接口
| 接口地址 | 请求方式 | 功能说明 |
|---|---|---|
| /api/auth/password/reset | POST | 重置密码 |
| /api/auth/password/change | POST | 修改密码(需登录) |
数据表结构
用户主表 (member)
| 字段名 | 类型 | 说明 |
|---|---|---|
| member_id | bigint | 会员ID,主键 |
| username | varchar(50) | 用户名 |
| password | varchar(255) | 加密密码 |
| nickname | varchar(50) | 昵称 |
| mobile | varchar(20) | 手机号 |
| varchar(100) | 邮箱 | |
| head_img | varchar(255) | 头像URL |
| status | tinyint | 状态:0-禁用,1-正常 |
| create_time | datetime | 创建时间 |
| update_time | datetime | 更新时间 |
| last_login_time | datetime | 最后登录时间 |
| last_login_ip | varchar(50) | 最后登录IP |
用户登录日志表 (member_login_log)
| 字段名 | 类型 | 说明 |
|---|---|---|
| log_id | bigint | 日志ID |
| member_id | bigint | 会员ID |
| login_type | tinyint | 登录类型 |
| login_ip | varchar(50) | 登录IP |
| login_time | datetime | 登录时间 |
| login_status | tinyint | 登录状态 |
| user_agent | varchar(500) | 浏览器UA |
安全机制
1. 密码安全
- 使用bcrypt算法加密存储
- 密码强度要求:6-20位,必须包含字母和数字
- 历史密码限制:不能重复使用最近5次密码
2. 验证码机制
- 图形验证码:防止暴力破解
- 短信验证码:5分钟有效期,60秒发送间隔
- 错误次数限制:连续错误5次锁定账号30分钟
3. Token安全
- 使用JWT Token机制
- Access Token有效期:2小时
- Refresh Token有效期:7天
- Token绑定设备信息
4. 登录安全
- 异地登录提醒
- 登录设备管理
- 单点登录控制
- 敏感操作二次验证
5. 传输安全
- 全站HTTPS加密
- 敏感数据加密传输
- 防重放攻击机制
- 请求签名验证
错误码说明
| 错误码 | 说明 |
|---|---|
| 10001 | 用户名已存在 |
| 10002 | 手机号已注册 |
| 10003 | 验证码错误 |
| 10004 | 验证码已过期 |
| 10005 | 账号或密码错误 |
| 10006 | 账号已被禁用 |
| 10007 | 账号已被锁定 |
| 10008 | Token已过期 |
| 10009 | Token无效 |
| 10010 | 密码强度不足 |
前端集成示例
登录页面示例
vue
<template>
<div class="login-container">
<el-form :model="loginForm" :rules="rules" ref="loginFormRef">
<el-form-item prop="account">
<el-input
v-model="loginForm.account"
placeholder="请输入用户名/手机号/邮箱"
prefix-icon="User"
/>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
type="password"
placeholder="请输入密码"
prefix-icon="Lock"
show-password
/>
</el-form-item>
<el-form-item v-if="showCaptcha" prop="captcha">
<div class="captcha-wrap">
<el-input v-model="loginForm.captcha" placeholder="请输入验证码"/>
<img :src="captchaUrl" @click="refreshCaptcha" class="captcha-img"/>
</div>
</el-form-item>
<el-button type="primary" :loading="loading" @click="handleLogin">
登录
</el-button>
</el-form>
</div>
</template>
<script setup>
import { ref, reactive } from 'vue'
import { useRouter } from 'vue-router'
import { login } from '@/api/auth'
import { useUserStore } from '@/stores/user'
const router = useRouter()
const userStore = useUserStore()
const loading = ref(false)
const showCaptcha = ref(false)
const captchaUrl = ref('')
const loginForm = reactive({
account: '',
password: '',
captcha: '',
captcha_key: ''
})
const rules = {
account: [{ required: true, message: '请输入账号', trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
captcha: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
}
const handleLogin = async () => {
loading.value = true
try {
const res = await login(loginForm)
userStore.setToken(res.data.token)
userStore.setUserInfo(res.data.user_info)
router.push('/')
} catch (error) {
if (error.code === 10007) {
showCaptcha.value = true
refreshCaptcha()
}
} finally {
loading.value = false
}
}
const refreshCaptcha = () => {
loginForm.captcha_key = Date.now()
captchaUrl.value = `/api/auth/captcha?key=${loginForm.captcha_key}`
}
</script>注意事项
- 密码传输:前端密码必须使用RSA加密后传输,禁止明文传输
- 验证码安全:图形验证码必须使用后立即失效
- 短信防刷:同一手机号发送短信有频率限制
- 登录失败处理:连续登录失败需要增加验证码或锁定账号
- Token刷新:Access Token过期前自动刷新,避免用户重新登录
- 多端登录:支持多端同时登录,可配置互踢策略
