文章目录
- 一.SpringCould+Vue3-Element-Admin 登录接口,用户信息接口以及Token验证的实现【VegePig教育平台】
- 1.1 背景
- 1.2 数据库
- 二、登录接口及其Token实现
- 2.1 前端
- 2.2 后端
- 2.2.1 控制层
- 2.2.2 service层
- 2.2.3 工具类:CreateJwt
- 2.2.4 Dao-Mapper
- 三、用户信息接口及其验证Token功能实现
- 3.1 前端
- 3.2 后端
- 3.2.1 控制层
- 3.2.3 service层
- 3.2.3 工具类:CreateJwt
- 3.2.4 Dao-Mapper
一.SpringCould+Vue3-Element-Admin 登录接口,用户信息接口以及Token验证的实现【VegePig教育平台】
1.1 背景
本项目为重构:行知在线综合教育平台。本项目更名为:VegePig教育平台
关键字:SpringBoot、SpringCould、Vue3、Uni-app
前端后台管理系统采用开源项目:Vue3-Element-Admin。
本文主要为了实现SpringCould+Vue3-Element-Admin 后台管理系统的登录接口,用户信息接口以及Token验证实现
1.2 数据库
二、登录接口及其Token实现
2.1 前端
前端采用开源项目:Vue3-Element-Admin
以下均为对Vue3-Element-Admin的代码魔改。
登录页面如下:
分析原始项目的请求接口返回值:
请求负载:
更改前端请求接口:
接口目录位置:Src->api->login.js
// 登录接口
export const Login = data => {
return request({
url: 'http://localhost:8001/user/login',
// url: '/api/login',
method: 'post',
data,
})
}
2.2 后端
2.2.1 控制层
后端接收到前端的传值:
后台登录:
@PostMapping("/user/login")
@ResponseBody //返回给前端一个文本格式
public Message login(@RequestBody BackLoginUser user) {
Message msg=new Message();
System.out.println(user.getUsername());
System.out.println(user.getPassword());
try {
if (StringUtils.isEmpty(user.getUsername())) {
msg.setMessage("登录失败,用户名不能为空");
msg.setStatus(400);
return msg;
}
if (StringUtils.isEmpty(user.getPassword())) {
msg.setMessage("登录失败,密码不能为空");
msg.setStatus(400);
return msg;
}
msg = sysUserService.doLogin(user);
return msg;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
代码解释:
@RequestBody BackLoginUser user:前端过来的json字符串存储到user。
user分别有username、password。
if (StringUtils.isEmpty(user.getUsername()))和 if (StringUtils.isEmpty(user.getPassword())) 是为了排除登录传值俩个字段为空的情况。
如果正常的话就继续往下。
没问题的话就传入了service层继续逻辑操作(查询用户是否存在,是否账号密码正确)
@Autowired
SysUserService sysUserService;
如下:
msg = sysUserService.doLogin(user);
return msg;
2.2.2 service层
代码如下:
public Message doLogin(BackLoginUser user) {
User userx = new User();
Message msg=new Message();
userx = sysUserDao.LoginByname(user.getUsername());
System.out.println(userx);
if (userx==null){
msg.setMessage("用户不存在,请注册!");
msg.setStatus(405);
return msg;
}else {
if (user.getUsername().equals(userx.getUsername())
&& user.getPassword().equals(userx.getPassword()) ){
String token = CreateJwt.getoken(userx);
Map<String, String> map = new HashMap<>();
map.put("token",token);
msg.setData(map);
msg.setMessage("登录成功");
msg.setStatus(200);
return msg;
}else {
msg.setMessage("登录失败,密码错误");
msg.setStatus(405);
return msg;
}
}
}
代码解释:
前面俩行没有可说的。
userx = sysUserDao.LoginByname(user.getUsername()); 调用了Dao层执行数据查询操作。
第一个if是排除用户不存在的问题(用户账号输错)。
else里分为登录成功或者密码错误。
登录成功代表需要生成Token。
String token = CreateJwt.getoken(userx);
2.2.3 工具类:CreateJwt
getoken方法为:生成Token,根据时间,用户的id,用户的用户名,现在的时间,和过期时间。过程如下。
private static final String key = "0123456789_0123456789_0123456789";
public static String getoken(User user) {
// 设置过期时间,这里设置为1小时
long expirationTime = System.currentTimeMillis() + 3600000;
SecretKey secretKey = new SecretKeySpec(key.getBytes(), SignatureAlgorithm.HS256.getJcaName());
String jwt = Jwts.builder()
.setId(user.getId()+"")
.setSubject(user.getUsername())
.setIssuedAt(new Date())
.setExpiration(new Date(expirationTime)) // 设置过期时间
.signWith(secretKey)
.compact();
return jwt;
}
2.2.4 Dao-Mapper
Dao:
public User LoginByname(String username);
Mapper:
<select id="LoginByname" parameterType="String" resultType="User">
select * from user where username = #{username};
</select>
三、用户信息接口及其验证Token功能实现
3.1 前端
获取登录用户信息:发起请求需要携带Token。发送给后端,后端需要验证Token才可返回值。
import axios from 'axios'
export const GetUserinfo = () => {
const token = localStorage.getItem('VEA-TOKEN');
return axios({
method: 'get',
url: 'http://localhost:8001/api/userinfo',
headers: {
'Authorization': 'Bearer ' + token,
}
});
};
发送过后,我们分析传回的值。
改动获取用户信息的data:data.data
原因:
我在对接后端接口之后无法实现用户的信息展示,排除后发现,我后端传来的值,如果想要取到data里的值,需要data.data。
// 获取用户信息
async getUserinfo() {
const { status, data } = await GetUserinfo()
if (+status === 200) {
this.userinfo = data.data
console.log("myurl:",data.data);
return Promise.resolve(data)
}
},
实现效果:
3.2 后端
3.2.1 控制层
用户信息
@GetMapping("/api/userinfo")
public Message getUserInfo(@RequestHeader("Authorization") String token,
@RequestHeader("User-Agent") String userAgent) {
Message msg=new Message();
try{
String[] parts = token.split("\\s+");
String jwtToken = parts[1];
System.out.println(jwtToken);
String tokenValue = JsonPath.parse(jwtToken).read("$.token");
System.out.println(tokenValue);
msg = sysUserService.userinfo(tokenValue);
return msg;
} catch (Exception e) {
return null;
}
代码解释
@RequestHeader(“Authorization”) String token,:接受前端传值Token。
try里面的值是我取字符串里面Token值的代码。
sysUserService.userinfo是把Token传入service进行处理。
msg = sysUserService.userinfo(tokenValue);
3.2.3 service层
代码如下:
public Message userinfo(String token) {
Message msg=new Message();
Claims claims = CreateJwt.parseToken(token);
User userx = new User();
System.out.println("claims.getId():"+claims.getId());
userx = sysUserDao.LoginById(claims.getId());
System.out.println(userx);
Map<String, String> map = new HashMap<>();
map.put("id", String.valueOf(userx.getId()));
map.put("name",userx.getName());
// role: 0 admin 1 teacher 0 student
String role = "";
if (userx.getRole()==0){
role="admin";
}if (userx.getRole()==1){
role="teacher";
}else {
role="student";
}
map.put("role",role);
map.put("avatar","https://s1.ax1x.com/2023/04/17/p9CjIr6.png");
msg.setData(map);
msg.setMessage("登录成功");
msg.setStatus(200);
return msg;
}
userinfo主要实现了token的解析,和返回值。
写到这里,我发现这块还没有写完,应该判断一下token解析的结果,如果错误的话返回状态码500。
role是一个简单的判断赋值:role: 0 admin 1 teacher 0 student
使用一个HashMap,将需要的数据值直接压入,最后放到Data里传递给后端。
3.2.3 工具类:CreateJwt
public static Claims parseToken(String token) {
System.out.println(token);
try {
SecretKey secretKey = new SecretKeySpec(key.getBytes(), SignatureAlgorithm.HS256.getJcaName());
Claims claims = Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
return claims;
} catch (ExpiredJwtException e) {
// Token已过期
System.out.println("Token已过期");
} catch (JwtException e) {
// Token解析失败
System.out.println("Token解析失败");
}
return null;
}
这块的代码是我用Chatgpt生成的,当然有我的小部分调试。Chatgpt写的相当不错。
这块主要是解析token的作用。
3.2.4 Dao-Mapper
Dao:
User LoginById(String id);
Mapper:
<select id="LoginById" parameterType="String" resultType="User">
select * from user where id = #{id};
</select>