回顾
上周内容比较简单, 只有两个接口:
- 添加用户
- 删除用户
接口: 重置密码
用户修改自己的密码, 是一个很常见的需求; 除此, 用户有可能忘记自己的密码, 需要让管理员为其重置密码. 接下来我们就来编写这两个接口吧.
接口: 管理员重置密码
需求分析:
管理员重置用户密码只需要知道用户名即可,不需要从前端接收新的密码, 我们可以在后端直接为用户生成一个固定的密码,如:123456
首先我们在mapper层编写重置密码的方法和对应的sql语句
1.打开UserInfoMapper.java
新增一个更新密码的方法
int updateUserPasswordByUserID(@Param("userID")int userID,@Param("password")String password, String salt);
2.打开UserInfoMapper.xml
编写更新密码的sql语句
<update id="updateUserPasswordByUserID">
UPDATE user_info
SET `password` = #{password},
salt = #{salt}
WHERE user_id= #{userID}
</update>
3.打开UserService
编写业务方法
void resetPassword(String userName) throws Exception;
4.打开UserServiceImpl
去实现3方法的具体操作
@Override
public void resetPassword(String userName) throws Exception {
//首先我们通过用户名取到用户ID
int userID = userInfoMapper.findFirstByUserName(userName).getUserId();
//初始化密码为123456
String password = "123456";
//利用UUID生成随机的盐值
String salt = UUID.randomUUID().toString().replace("-","");
//使用MD5算法和盐值生成密文
SimpleHash simpleHash = new SimpleHash(Md5Hash.ALGORITHM_NAME,password,salt,512);
//修改数据库中对应用户的盐值和密文
userInfoMapper.updateUserPasswordByUserID(userID,simpleHash.toString(),salt);
}
5.最后在UserController
中调用service的方法
@PutMapping("/resetPassword")
@RequiresRoles(value = {"admin"},logical = Logical.OR)
@ApiImplicitParams({
@ApiImplicitParam(name = "token", value = "鉴权用户",required = true,paramType = "header"),
@ApiImplicitParam(name = "userName")
})
public ResultJson resetPassword(String userName){
try {
userService.resetPassword(userName);
return new ResultJson("200","密码成功重置为123456","");
}catch (Exception e){
return new ResultJson("400","failed","");
}
}
接口: 用户重置密码
需求分析:
- 用户必须是登录状态
- 要求用户输入旧密码进行验证
- 输入新密码
由于对数据库的操作是一模一样的, 所以我们mapper层就不用再写一次了, 复用刚才写好的就行啦! 直接从service层开始就好
1.打开UserService
编写用户修改的业务方法
void resetSelfPassword(String userName, String password) throws Exception;
2.在UserServiceImpl
中实现它
@Override
public void resetSelfPassword(String userName, String password) throws Exception {
//这里业务逻辑和管理员重置密码几乎一样
//唯一的差别就是用户重置的密码的通过前端传来的, 而不是一个固定的值
//注意考虑考虑代码复用的问题, 这就留给你们自己思考啦!
//通过用户名取得用户ID
int userID = userInfoMapper.findFirstByUserName(userName).getUserId();
//使用UUID生成随机的盐值
String salt = UUID.randomUUID().toString().replace("-","");
//通过MD5算法和盐值共同生成密文
SimpleHash simpleHash = new SimpleHash(Md5Hash.ALGORITHM_NAME,password,salt,512);
//修改数据库中对应用户的盐值和密文
userInfoMapper.updateUserPasswordByUserID(userID,simpleHash.toString(),salt);
}
3.最后在UserController
中编写接口
@ApiImplicitParams({
@ApiImplicitParam(name = "token", value = "鉴权用户", required = true, paramType = "header"),
@ApiImplicitParam(name = "oldPassword", value = "旧密码", required = true),
@ApiImplicitParam(name = "newPassword", value = "新密码", required = true)
})
@PutMapping("/resetSelfPassword")
public ResultJson resetSelfPassword(String oldPassword, String newPassword){
//由于用户已经是登录的, 这里可以直接取出用户的信息
Subject subject = SecurityUtils.getSubject();
UserInfo userInfo = (UserInfo) subject.getPrincipals().getPrimaryPrincipal();
String userName = userInfo.getUserName();
String salt = userInfo.getSalt();
//将用户传入的旧密码和数据库中的密码进行匹配
//注意我们数据库中存储的密码是密文, 且MD5加密算法不可逆
//所以我们要将用户传入的旧密码进行加密,用密文和数据库中的密码进行匹配
SimpleHash simpleHash = new SimpleHash(Md5Hash.ALGORITHM_NAME,oldPassword,salt,512);
if(!simpleHash.toString().equals(userInfo.getPassword())){
return new ResultJson("400","修改密码失败, 原密码不匹配!",null);
}else {
try {
userService.resetSelfPassword(userName,newPassword);
return new ResultJson("200","密码修改成功!",null);
}catch (Exception e){
e.printStackTrace();
return new ResultJson("400","密码修改失败",null);
}
}
}
这样我们的两个简单的重置密码接口就写好啦.
常用的用户接口
- 获取所有用户信息
- 根据用户名获取单个用户信息
- 管理员修改用户当前状态
- 修改用户所属角色
接口: 根据用户名获取用户信息
分析: 在实际应用中, 哪些数据是应该返回给前端的, 哪些数据是不应该的; 首先密码, 盐值这显然不需要返回给用户, 一般来说前端还会需要知道这个用户所属的角色, 甚至是用户具有的权限等…
由于我们返回的数据类型比较复杂, 所以通常我们会用对象(JSON)的方式来展示数据, 一般来说会有个VO层, 有兴趣的同学可以了解一下
1.编写用来展示用户数据的vo
2.在UserService
层中编写方法, 并在UserServiceImpl
中实现它
3.在UserController
中调用service
4.结果: 最终我们拿到的数据格式就是这样的啦
接口: 获取所有用户信息
能获取一个, 获取所有就很简单啦, 这里就不细写了, 提示: 将前面我们写的获取单个用户的service改造一下, 把返回值VoUserInfo改为List< VoUserInfo>
给你们个结果参考吧:
接口: 管理员修改用户状态
用户状态我们在Shrio中有配置过, 如果其状态2的时候, 禁用该用户
那我们就来写一个禁用用户的接口吧
1.mapper中编写sql和对应方法
2.service中编写业务方法并在Impl层中实现它
3.controller中调用service
4.结果
尝试使用刚才禁用的用户登录:
接口启用用户同理, 这里就不写啦 !
接口: 修改用户所属角色
注意一个细节, 用户和角色之间的关系是多对多,
前端在接收参数的时候应该是接收一个用户名 和 角色名称的数组
也就是说, 在数据库中, 如果用户ID为1的用户拥有多个角色, 在更新该用户信息的时候的SQL就不应该使用update table set field=value
的方式! ! !
而应该将其所拥有的角色delete
再执行insert
1.mapper层编写对应的sql
2.service层编写对应的业务逻辑并在impl层实现它
3.controller层中调用service
4.结果:
我们先来看看用户admin的角色信息
我们试着将其的manager角色删除, 只保留admin角色
再试试将admin, manager, staff三个角色都赋给用户admin