勋的要求
1 登录后 后端返回一个token
2 数据库 用户表 事项表
用户表:用户名 密码 用户标识(id)
1 zhangsan 123456
2 zhangsan2 123456
3 zhangsan3 123456
事项表:事项基本信息(事项id,名称、创建时间、完成状态、完成时间),所属用户 权限?
id name uid datetime status ...
1 学习VUE 3 .....
2 学习HTML 3 .....
3 学习VUE 1 .....
4 学习VUE 2 .....
3 添加事项:
前端通过POST:事项的基本信息(post),token
后端:解析token,将uid和事项信息存储数据库(INSERT)
返回:返回操作的结果(成功、失败)
4 查询事项:
前端:GET请求,携带token
后端:解析token,得到uid,在数据库中查询(SELECT)Where uid=?
返回:返回查询结果(List)【事项id,事项名称,事项状态...】
5 修改事项:
前端:POST请求,携带token,事项id,更新后的事项的数据
后端:解析token得到uid,更具事项id(1,2,3,4,5,6,7),更新数据库中的事项内容(UPDATE where id = ? and uid = ?)
@RestController
@RequestMapping("/tasks")
public class TaskController {
@Autowired
private TaskService taskService;
@Autowired
private UserService userService; // 确保 UserService 能够被注入
@GetMapping("/mytasks")
public ResponseEntity<?> getMyTasks(@RequestHeader("Authorization") String token) {
try {
// 从 token 中获取用户信息
User user = userService.getUserInfoByToken(token);
// 使用用户ID获取任务列表
List<Task> tasks = taskService.getTasksByUserId(user.getId());
return ResponseEntity.ok(tasks);
} catch (Exception e) {
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(e.getMessage());
}
}
}
@Service
public class TaskService {
@Autowired
private TaskMapper taskMapper;
@Transactional(readOnly = true)
public List<Task> getTasksByUserId(Integer userId) {
return taskMapper.findByUserId(userId);
}
}
@Mapper
public interface TaskMapper {
List<Task> findByUserId(Integer userId);
}
XML文件
<select id="findByUserId" resultMap="taskResultMap">
SELECT * FROM tasks WHERE uid = #{userId}
</select>
后端实现
配置环境
实体类代码:
import lombok.Data;
import java.util.Date;
@Data
public class User {
private Integer id;
private String username;
private String password;
private String name;
private String gender;
private Date birthDate;
}
import lombok.Data;
@Data
public class Task {
private Long id;
private String name;
private Integer uid;
private Boolean completed;
}
前后端交互统一响应结果 Result
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
private Integer code;//响应码,1 代表成功; 0 代表失败
private String msg; //响应信息 描述字符串
private Object data; //返回的数据
//增删改 成功响应
public static Result success(){
return new Result(1,"success",null);
}
//查询 成功响应
public static Result success(Object data){
return new Result(1,"success",data);
}
//失败响应
public static Result error(String msg){
return new Result(0,msg,null);
}
}
数据库格式:
`tasks`(`id`, `name`, `uid`, `completed`)
`user`(`id`, `username`, `password`, `name`, `gender`, `birth_date`)
数据库建表语句:
CREATE TABLE User (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
name VARCHAR(255),
gender VARCHAR(10),
birth_date DATE
);
CREATE TABLE Task (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
uid INT,
completed TINYINT(1) DEFAULT 0
);
配置文件代码:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo0414
username: root
password: 123456
mybatis:
configuration:
#配置mybatis的日志, 指定输出到控制台
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#开启mybatis的驼峰命名自动映射开关 a_column ------> aCloumn
map-underscore-to-camel-case: true
配置 mapper XML文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.minjie.mapper.UserMapper">
</mapper>
JWT令牌实现登录校验
引入依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
JwtUtils 代码
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.Map;
public class JwtUtils {
private static String signKey = "itheima";
private static Long expire = 43200000L;
/**
* 生成JWT令牌
* @param claims JWT第二部分负载 payload 中存储的内容
* @return
*/
public static String generateJwt(Map<String, Object> claims){
String jwt = Jwts.builder()
.addClaims(claims)
.signWith(SignatureAlgorithm.HS256, signKey)
.setExpiration(new Date(System.currentTimeMillis() + expire))
.compact();
return jwt;
}
/**
* 解析JWT令牌
* @param jwt JWT令牌
* @return JWT第二部分负载 payload 中存储的内容
*/
public static Claims parseJWT(String jwt){
Claims claims = Jwts.parser()
.setSigningKey(signKey)
.parseClaimsJws(jwt)
.getBody();
return claims;
}
}
在 controller 进行发令牌的判断和操作
添加用户请求体内容
{
"username":"郑爽",
"password":"111",
"name":"爽",
"gender":"女",
"birthdate":"1989-01-01"
}
MD5密码加密
理论学习
对称加密:使用同一把密钥
非对称加密:公钥:加密 / 私钥:解密
摘要算法:哈希算法 / 散列算法,不可逆,MD5
代码实现
前端实现
勋的实现:
<template>
<div class="task-list">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>我的任务列表</span>
</div>
<el-table :data="tasks" style="width: 100%">
<el-table-column prop="name" label="任务名称" width="180"></el-table-column>
<el-table-column prop="completed" label="完成状态" width="100">
<template slot-scope="scope">
<el-tag :type="scope.row.completed ? 'success' : 'info'">
{{ scope.row.completed ? '已完成' : '未完成' }}
</el-tag>
</template>
</el-table-column>
</el-table>
</el-card>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
tasks: []
};
},
created() {
this.fetchTasks();
},
methods: {
fetchTasks() {
const token = localStorage.getItem('token');
axios.get('/api/tasks/mytasks', {
headers: {
'Authorization': token
}
})
.then(response => {
this.tasks = response.data;
})
.catch(error => {
this.$message.error('获取任务列表失败');
});
}
}
};
</script>
<style scoped>
.task-list {
margin: 20px;
}
.box-card {
width: 500px;
}
</style>
知识点
1. MD5 和 JWT 并没有直接的关系,因为它们解决的问题和功能不同。在实际的身份验证流程中,MD5 可能用于加密用户密码,而 JWT 则可能用于生成和验证用户的身份令牌,这样用户可以在多个服务中进行身份验证而无需重复登录。
2.
如图,加了 @JsonIgnore 之后就添加也会忽略,报错 500
报错
405:post 请求写成 get 请求
500:加了 @JsonIgnore