完整 Spring Boot + Vue 登录系统

发布于:2025-07-14 ⋅ 阅读:(22) ⋅ 点赞:(0)

项目名称:springboot-vue-login-template


✅ 功能一览

模块 功能
后端 Spring Boot + MyBatis Plus + JWT + Shiro
数据库 MySQL 用户表
前端 Vue3 + Element Plus + Axios
登录流程 用户名/密码验证 → 返回 Token → 存储 LocalStorage
权限控制 拦截器校验 Token + Shiro 角色权限
跨域配置 后端支持跨域请求
接口安全 所有接口需携带 Token 访问

📁 项目结构概览

springboot-vue-login-template/
├── backend/             # Spring Boot 后端模块
│   ├── src/main/java      # Java源码
│   ├── src/main/resources # 配置文件
│   └── pom.xml            # Maven依赖管理
├── frontend/            # Vue3 前端模块
│   ├── public/
│   ├── src/
│   │   ├── views/         # 页面组件
│   │   ├── utils/         # 工具类
│   │   └── main.js        # 入口文件
│   └── package.json       # 依赖管理
└── README.md              # 项目说明文档

🧱 数据库脚本(MySQL)

CREATE DATABASE springboot_login;

USE springboot_login;

CREATE TABLE sys_user (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) NOT NULL UNIQUE,
    password VARCHAR(100) NOT NULL,
    nickname VARCHAR(50),
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- 示例用户(密码为123456)
INSERT INTO sys_user (username, password, nickname)
VALUES ('admin', '$2a$10$eACCYoNOHEzWZhE8Cwe6gOXEpTLExV6l', '管理员');

🚀 后端代码(Spring Boot)

1. application.yml

server:
  port: 8080

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/springboot_login?useSSL=false&serverTimezone=UTC
    username: root
    password: yourpassword
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis-plus:
  mapper-locations: classpath:/mapper/*.xml

2. JWT 工具类 JwtUtils.java

import io.jsonwebtoken.*;
import java.util.Date;

public class JwtUtils {
    private static final String SECRET = "your-secret-key";
    private static final long EXPIRATION = 86400000; // 24小时

    public static String generateToken(String username) {
        return Jwts.builder()
            .setSubject(username)
            .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION))
            .signWith(SignatureAlgorithm.HS512, SECRET)
            .compact();
    }

    public static String parseToken(String token) {
        return Jwts.parser()
            .setSigningKey(SECRET)
            .parseClaimsJws(token)
            .getBody()
            .getSubject();
    }
}

3. 登录接口 AuthController.java

@RestController
@RequestMapping("/api/auth")
public class AuthController {

    @Autowired
    private UserService userService;

    @PostMapping("/login")
    public ResponseEntity<?> login(@RequestBody LoginRequest request) {
        SysUser user = userService.findByUsername(request.getUsername());
        if (user == null || !user.getPassword().equals(request.getPassword())) {
            throw new RuntimeException("用户名或密码错误");
        }

        String token = JwtUtils.generateToken(user.getUsername());

        return ResponseEntity.ok()
            .header("Authorization", "Bearer " + token)
            .build();
    }
}

4. 自定义拦截器 JwtInterceptor.java

@Component
public class JwtInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("Authorization");

        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7);
            String username = JwtUtils.parseToken(token);

            UsernamePasswordToken shiroToken = new UsernamePasswordToken(username, "");
            SecurityUtils.getSubject().login(shiroToken);
        }

        return true;
    }
}

5. 注册拦截器 WebConfig.java

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private JwtInterceptor jwtInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/api/auth/login");
    }
}

🖥️ 前端代码(Vue3 + Element Plus)

1. 安装依赖

npm install axios element-plus

2. 登录页面组件 Login.vue

<template>
  <div style="max-width: 400px; margin: 100px auto;">
    <h2>登录</h2>
    <el-input v-model="username" placeholder="用户名"></el-input>
    <el-input v-model="password" type="password" placeholder="密码" @keyup.enter.native="login"></el-input>
    <el-button @click="login" type="primary">登录</el-button>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import axios from 'axios';

const router = useRouter();
const username = ref('');
const password = ref('');

const login = async () => {
  try {
    const res = await axios.post('http://localhost:8080/api/auth/login', {
      username: username.value,
      password: password.value
    });
    const token = res.headers.authorization;
    localStorage.setItem('token', token);
    router.push('/home');
  } catch (error) {
    alert('登录失败');
  }
};
</script>

3. Axios 请求封装 utils/request.js

import axios from 'axios';

const service = axios.create({
  baseURL: 'http://localhost:8080',
  timeout: 5000
});

service.interceptors.request.use(config => {
  const token = localStorage.getItem('token');
  if (token) {
    config.headers.Authorization = token;
  }
  return config;
});

export default service;

📝 项目启动说明(README.md)

# Spring Boot + Vue 登录系统模板

## 后端启动

1. 创建数据库并导入数据
2. 修改 `application.yml` 中的数据库配置
3. 使用 IDEA 或命令行运行 Spring Boot 项目:

```bash
cd backend
mvn spring-boot:run

前端启动

cd frontend
npm install
npm run serve

访问 http://localhost:8081


网站公告

今日签到

点亮在社区的每一天
去签到