Files
rxthinkcmf-wiki/RXThinkCMF_ThinkPhp6_EleVue/zh/frontend/login.md
T
2026-09-29 09:49:04 +08:00

1.9 KiB

9.8 登录流程

:::tip 概述 本节说明前端登录流程的实现,包括登录表单提交、Token 存储、路由守卫和登出处理。 :::

前端登录流程

1. 用户输入用户名、密码、验证码
2. 调用 POST /api/login 接口
3. 成功 → 存储 Token 到 localStorage
4. 路由守卫检测到 Token → 获取用户信息
5. 生成动态路由 → 跳转首页

登录页面代码

<!-- src/views/login/index.vue -->
<template>
  <el-form :model="loginForm" @submit.prevent="handleLogin">
    <el-form-item>
      <el-input v-model="loginForm.username" placeholder="用户名" />
    </el-form-item>
    <el-form-item>
      <el-input v-model="loginForm.password" type="password" placeholder="密码" />
    </el-form-item>
    <el-form-item>
      <el-input v-model="loginForm.captchaCode" placeholder="验证码" />
      <img :src="captchaImage" @click="refreshCaptcha" />
    </el-form-item>
    <el-button type="primary" @click="handleLogin">登录</el-button>
  </el-form>
</template>

<script setup>
import { useUserStore } from '@/store/modules/user';
import { getCaptcha } from '@/api/common/user';

const userStore = useUserStore();
const loginForm = ref({ username: '', password: '', captchaCode: '', captchaKey: '' });
const captchaImage = ref('');

// 获取验证码
const refreshCaptcha = async () => {
  const res = await getCaptcha();
  loginForm.value.captchaKey = res.key;
  captchaImage.value = res.image;
};

// 登录
const handleLogin = async () => {
  await userStore.login(loginForm.value);
  router.push('/');
};

onMounted(() => refreshCaptcha());
</script>

Token 存储

// 登录成功后存储
storage.set(ACCESS_TOKEN, data.access_token, 7 * 24 * 60 * 60 * 1000);  // 7天过期

// 请求拦截器自动携带
config.headers['Authorization'] = `Bearer ${token}`;

// 响应拦截器检测 401
if (response.data.code === 401) {
    router.push('/login');
}