SpringBoot + MySQL + JWT 实现前后端分离的在线教育视频点播平台
《基于 SpringBoot + MySQL + JWT 的前后端分离在线教育视频点播平台》
✅ 前后端分离
✅ JWT 鉴权
✅ 视频点播
✅ 权限分级
✅ 技术栈主流,面试也能打
一、选题背景(论文可直接用)
随着"互联网+教育"的快速发展,传统线下教学模式存在以下局限:
教学资源受时间空间限制
课程缺乏统一管理
学习进度难以追踪
权限管理混乱,资源易泄露
本系统基于SpringBoot + MySQL + JWT,实现:
✅ 前后端分离架构
✅ 安全认证与权限控制
✅ 视频课程在线点播
✅ 学习进度记录
具有较强的实用价值和推广前景。
二、技术架构
前端(Vue / React) ↓ Axios + JWT SpringBoot(后端) ├── 用户模块 ├── 课程模块 ├── 视频点播模块 ├── 权限模块(JWT) └── 学习记录模块 ↓ MySQL(持久化存储)技术 | 作用 |
|---|---|
SpringBoot | 快速开发 |
MyBatis | ORM |
MySQL | 数据存储 |
JWT | 无状态鉴权 |
Spring Security(可选) | 权限控制 |
Vue + Axios | 前端交互 |
视频存储 | 本地 / 云存储(OSS / COS) |
三、系统角色设计
1️⃣ 管理员
用户管理
课程管理
视频上传与审核
数据统计
2️⃣ 教师
发布课程
上传教学视频
查看学生学习进度
3️⃣ 学生
注册 / 登录
浏览课程
在线播放视频
查看学习记录
四、核心业务流程(答辩必画)
用户注册 / 登录 ↓ 获取 JWT Token ↓ 携带 Token 请求接口 ↓ 浏览课程列表 ↓ 选择课程 → 在线播放视频 ↓ 记录学习进度五、数据库设计(核心表)
1️⃣ 用户表user
CREATE TABLE user ( id BIGINT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(50) UNIQUE, password VARCHAR(100), real_name VARCHAR(50), role VARCHAR(20) DEFAULT 'STUDENT' );2️⃣ 课程表course
CREATE TABLE course ( id BIGINT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(100), description TEXT, cover_url VARCHAR(200), teacher_id BIGINT, status INT DEFAULT 1, create_time DATETIME );3️⃣ 视频表video
CREATE TABLE video ( id BIGINT PRIMARY KEY AUTO_INCREMENT, course_id BIGINT, title VARCHAR(100), video_url VARCHAR(300), duration INT COMMENT '秒', sort INT );4️⃣ 学习记录表learning_record
CREATE TABLE learning_record ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id BIGINT, video_id BIGINT, progress INT COMMENT '播放进度(秒)', finished TINYINT DEFAULT 0, update_time DATETIME );六、JWT 鉴权核心实现(⭐重点)
1️⃣ 引入依赖
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.11.5</version> </dependency>2️⃣ JWT 工具类
@Component public class JwtUtil { private final String SECRET = "edu-platform-secret-key"; public String generateToken(Long userId, String role) { return Jwts.builder() .setSubject(String.valueOf(userId)) .claim("role", role) .setIssuedAt(new Date()) .setExpiration(new Date(System.currentTimeMillis() + 86400000)) .signWith(Keys.hmacShaKeyFor(SECRET.getBytes()), SignatureAlgorithm.HS256) .compact(); } public Claims parseToken(String token) { return Jwts.parserBuilder() .setSigningKey(SECRET.getBytes()) .build() .parseClaimsJws(token) .getBody(); } }3️⃣ 登录接口
@PostMapping("/login") public R<Map<String, String>> login(@RequestBody LoginRequest req) { User user = userService.login(req.getUsername(), req.getPassword()); if (user == null) { return R.fail("用户名或密码错误"); } String token = jwtUtil.generateToken(user.getId(), user.getRole()); Map<String, String> data = new HashMap<>(); data.put("token", token); data.put("role", user.getRole()); return R.ok(data); }4️⃣ JWT 拦截器
@Component public class JwtInterceptor implements HandlerInterceptor { @Autowired private JwtUtil jwtUtil; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String authHeader = request.getHeader("Authorization"); if (authHeader == null || !authHeader.startsWith("Bearer ")) { response.setStatus(401); return false; } String token = authHeader.substring(7); try { Claims claims = jwtUtil.parseToken(token); request.setAttribute("userId", claims.getSubject()); request.setAttribute("role", claims.get("role")); return true; } catch (Exception e) { response.setStatus(401); return false; } } }5️⃣ 注册拦截器
@Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private JwtInterceptor jwtInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(jwtInterceptor) .addPathPatterns("/api/**") .excludePathPatterns("/api/user/login", "/api/user/register"); } }七、视频点播核心实现
1️⃣ 课程列表接口
@GetMapping("/api/course/list") public R<List<Course>> listCourses() { return R.ok(courseService.listPublished()); }2️⃣ 视频播放接口
@GetMapping("/api/video/play/{id}") public R<VideoVO> playVideo(@PathVariable Long id, HttpServletRequest request) { Long userId = (Long) request.getAttribute("userId"); Video video = videoService.getById(id); if (video == null) { return R.fail("视频不存在"); } // 记录学习进度 learningService.recordPlay(userId, id); return R.ok(VideoVO.from(video)); }3️⃣ 学习进度记录
@PostMapping("/api/learning/progress") public R<Void> updateProgress(@RequestBody ProgressRequest req, HttpServletRequest request) { Long userId = (Long) request.getAttribute("userId"); learningService.updateProgress(userId, req.getVideoId(), req.getProgress()); return R.ok(); }4️⃣ 学习记录 Service
@Transactional public void recordPlay(Long userId, Long videoId) { LearningRecord record = recordMapper.selectByUserAndVideo(userId, videoId); if (record == null) { record = new LearningRecord(); record.setUserId(userId); record.setVideoId(videoId); record.setProgress(0); record.setFinished(false); recordMapper.insert(record); } recordMapper.updateTime(record.getId()); }八、前端请求示例(Vue + Axios)
// 登录 const res = await axios.post('/api/user/login', { username: 'student1', password: '123456' }); localStorage.setItem('token', res.data.token); // 携带 Token 请求课程 axios.get('/api/course/list', { headers: { Authorization: 'Bearer ' + localStorage.getItem('token') } });九、系统特色(⭐答辩亮点)
✅ 前后端完全分离
✅ JWT 无状态鉴权,适合分布式部署
✅ 视频点播 + 学习进度跟踪
✅ 角色权限分级(管理员 / 教师 / 学生)
✅ RESTful 风格接口
✅ 可扩展为微服务 / 接入云点播
十、安全防护(加分项)
✅ Token 过期机制
✅ 密码加密(BCrypt)
✅ 接口防刷(Redis + 限流)
✅ 视频防盗链(Token + 时效 URL)
✅ XSS / SQL 注入防护
十一、毕设论文结构建议
章节 | 内容 |
|---|---|
第1章 | 绪论 |
第2章 | 相关技术(SpringBoot、JWT、Vue) |
第3章 | 需求分析 |
第4章 | 系统设计(E-R图、架构图) |
第5章 | 系统实现(JWT鉴权 + 视频点播) |
第6章 | 系统测试 |
第7章 | 总结与展望 |
十二、可扩展方向(体现工作量)
✅ 视频弹幕 / 评论
✅ 课程付费 & 订单系统
✅ 直播教学(WebRTC / RTMP)
✅ 学习数据分析(ECharts)
✅ 移动端适配 / 小程序
✅ 接入阿里云 / 腾讯云点播
