JWT 持久化
登录成功后将 access_token 写入 localStorage,作为后续 API 请求的 Authorization 凭证。
Login.vue 承担了系统的安全门户职责。它不仅负责前端表单的原子级校验,还处理了后端返回的 JWT (JSON Web Token) 存储,并根据用户角色的 is_admin 字段执行不同的路由分发策略。
组件在单一视图内通过 isLogin 状态实现登录与注册逻辑的平滑切换。
JWT 持久化
登录成功后将 access_token 写入 localStorage,作为后续 API 请求的 Authorization 凭证。
角色路由分发
自动识别 user.is_admin 标志位,管理员强制重定向至 /admin 后台,普通用户则通过 emit 通知主页刷新。
表单原子校验
集成密码长度截断检查与正则表达式邮箱格式校验,减少无效的后端请求开销。
isLogin 状态,动态调整表单字段渲染(如注册模式下展示学校、邮箱)。axios 向 /auth/login 或 /auth/register 发起异步请求。/** * @description 统一表单状态管理,确保与后端 User 模型字段严格映射 */const form = reactive({ username: '', password: '', real_name: '', // 对应后端映射名 email: '', school: ''});/** * @description 处理认证请求的核心控制器 */const handleSubmit = async () => { // Step 1: 客户端防御性编程,减少服务器压力 if (form.password.length < 6) { Swal.fire({ icon: 'warning', text: 'Password must be at least 6 characters.' }); return; }
// Step 2: 动态 Endpoint 选择 const endpoint = isLogin.value ? '/auth/login' : '/auth/register'; loading.value = true;
try { const response = await axios.post(endpoint, form);
if (isLogin.value) { handleLoginSuccess(response.data); } else { handleRegisterSuccess(); } } catch (error: any) { handleAuthError(error); } finally { loading.value = false; }};/** * @description 处理登录成功后的凭证持久化与路由跳转 */const handleLoginSuccess = (data: any) => { const { access_token, user } = data;
// 持久化存储,键名:cpd_token localStorage.setItem('cpd_token', access_token); localStorage.setItem('cpd_user_info', JSON.stringify(user));
if (user.is_admin) { // 管理员重定向 router.push('/admin'); } else { // 普通用户回调 emit('login-success'); }};| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
username | string | 是 | 用户唯一标识 |
password | string | 是 | 原始密码字符串 |
real_name | string | 仅注册 | 真实姓名,用于报表抬头 |
email | string | 仅注册 | 符合正则规则的邮箱 |
{ "access_token": "eyJhbGciOiJIUzI1NiI...", "user": { "username": "admin", "is_admin": true }}