前情提要:本demo是基于springboot+mybatis-plus实现加密,加密为主,全局异常处理,日志处理为辅,而登录密码加密是每个项目中必须要的,密码不可能明文存入数据,这样没有安全性。
涉及的功能,全局异常处理,日志处理,mybatis-plus实现与数据库的交互,密码加密,restful风格
涉及的工具:IDEA,postman,sqlyog(navicat)
1. 首先我们直接看效果吧,如果你不满意,也就没必要看了
如果这正是你想要的效果呢,那你可以继续看下面的内容了
2. 首先,我们看下pom.xml文件
以下依赖为所需的主要依赖
4.0.0 org.springframework.boot spring-boot-starter-parent2.2.4.RELEASE com.jgsu springboot_rsa_encryption0.0.1-SNAPSHOT springboot_encryption Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter-weborg.springframework.boot spring-boot-starter-testtest org.springframework.boot spring-boot-devtoolstrue mysql mysql-connector-java5.1.47 org.projectlombok lombok1.16.20 com.alibaba druid-spring-boot-starter1.1.10 com.baomidou mybatis-plus-boot-starter3.2.0 org.springframework.boot spring-boot-starter-security2.1.6.RELEASE com.alibaba fastjson1.2.51 org.springframework.boot spring-boot-maven-plugin
3. 创建启动类SpringbootEncryptionApplication
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@SpringBootApplication
@MapperScan("com.jgsu.mapper")
public class SpringbootEncryptionApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootEncryptionApplication.class, args);
}
@Bean
public BCryptPasswordEncoder encoder() {
return new BCryptPasswordEncoder();
}
}
4.实体类
这里只有用户名和密码(其他数据自己可扩展)
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")
public class User {
@TableId(value = "id",type = IdType.AUTO)
private int id;
private String username;
private String password;
}
5. service层(业务层)
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jgsu.entity.User;
import com.jgsu.exception.DataAddException;
import com.jgsu.exception.DataMatchException;
import com.jgsu.mapper.UserMapper;
import com.jgsu.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class UserServiceImpl implements UserService {
@Autowired
UserMapper userMapper;
// 数据加密,在启动类中已经注入进IOC容器中
@Autowired
private BCryptPasswordEncoder encoder;
@Override
public User userLogin(String username,String password) {
// mybatis-plus的条件构造器,这里实现根据username查询
QueryWrapper wrapper = new QueryWrapper();
wrapper.eq("username", username);
User userLogin = userMapper.selectOne(wrapper);
if (userLogin != null && encoder.matches(password, userLogin.getPassword())) {
log.info("用户{},登录成功",username);
return userLogin;
} else {
log.error("用户名或密码错误");
throw new DataMatchException("405", "用户名或密码错误");
}
}
@Override
public User userRegister(String username, String password) {
User user = new User();
user.setId(user.getId());
user.setUsername(username);
user.setPassword(encoder.encode(password));
int i = userMapper.insert(user);
if (i == 1){
log.info("用户{}注册成功",username);
return user;
}else {
log.error("服务器发生异常,注册失败");
throw new DataAddException("403","注册失败");
}
}
}
6. mapper层
如果不了解,可以建议去看看mybatis-plus官方文档
import com.baomidou.mybatisplus.core.mapper.baseMapper; import com.jgsu.entity.User; import org.springframework.stereotype.Repository; @Repository public interface UserMapper extends baseMapper{ }
7.controller层
import com.jgsu.entity.User;
import com.jgsu.service.UserService;
import com.jgsu.utils.CommonResult;
import com.jgsu.utils.ResultCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
UserService userService;
// 注册,基于restful风格
@GetMapping("/register/{username}/{password}")
public CommonResult register(@PathVariable("username") String username,@PathVariable("password") String password){
User user = userService.userRegister(username, password);
if (user != null){
return CommonResult.success(ResultCode.SUCCESS);
}else {
return CommonResult.failed(ResultCode.FAILED);
}
}
// 登录,基于restful风格
@GetMapping("/login/{username}/{password}")
public CommonResult login(@PathVariable("username") String username,@PathVariable("password") String password) {
User userLogin = userService.userLogin(username,password);
if (userLogin != null) {
return CommonResult.success(ResultCode.SUCCESS);
} else {
return CommonResult.failed(ResultCode.USERNAME_OR_PASSWORD_ERROR);
}
}
}
8.配置类(返回json数据的类)
封装错误码的接口
public interface IErrorCode {
long getState();
String getMessage();
}
枚举了一些常用API操作码
public enum ResultCode implements IErrorCode {
SUCCESS(200, "ok"),
FAILED(500, "server error"),
VALIDATE_FAILED(404, "undefined"),
UNAUTHORIZED(401, "未登录"),
USERNAME_OR_PASSWORD_ERROR(405, "用户名或密码错误"),
DATA_Not_Exist_ERROR(603, "数据不存在"),
DATA_ADD_ERROR(604, "数据添加异常"),
FILE_ERROR(605, "上传文件出现错误"),
IMAGE_ERROR(606, "图片处理出现错误"),
FORBIDDEN(403, "forbidden");
private long state;
private String stateInfo;
ResultCode(long state, String stateInfo) {
this.state = state;
this.stateInfo = stateInfo;
}
@Override
public long getState() {
return state;
}
@Override
public String getMessage() {
return stateInfo;
}
}
通用返回对象
public class CommonResult{ private long state; private String stateInfo; private T data; public CommonResult() { } public CommonResult(long state, String stateInfo, T data) { this.state = state; this.stateInfo = stateInfo; this.data = data; } public CommonResult(long state, String stateInfo) { this.state = state; this.stateInfo = stateInfo; } public static CommonResult success(T data) { return new CommonResult (ResultCode.SUCCESS.getState(), ResultCode.SUCCESS.getMessage(), data); } public static CommonResult success(T data, String message) { return new CommonResult (ResultCode.SUCCESS.getState(), message, data); } public static CommonResult failed(IErrorCode errorCode) { return new CommonResult (errorCode.getState(), errorCode.getMessage(), null); } public static CommonResult failed(String message) { return new CommonResult (ResultCode.FAILED.getState(), message, null); } public static CommonResult failed(int code, String message) { return failed(ResultCode.FAILED); } public static CommonResult validateFailed() { return failed(ResultCode.VALIDATE_FAILED); } public static CommonResult validateFailed(String message) { return new CommonResult (ResultCode.VALIDATE_FAILED.getState(), message, null); } public static CommonResult unauthorized(T data) { return new CommonResult (ResultCode.UNAUTHORIZED.getState(), ResultCode.UNAUTHORIZED.getMessage(), data); } public static CommonResult forbidden(T data) { return new CommonResult (ResultCode.FORBIDDEN.getState(), ResultCode.FORBIDDEN.getMessage(), data); } public long getState() { return state; } public void setState(long state) { this.state = state; } public String getStateInfo() { return stateInfo; } public void setStateInfo(String stateInfo) { this.stateInfo = stateInfo; } public T getData() { return data; } public void setData(T data) { this.data = data; } }
9. 异常类
全局异常拦截类
@Slf4j
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHander {
@ExceptionHandler(value = Exception.class)
public CommonResult handlerException(Exception e){
if (e instanceof DataAddException){
log.error("【全局异常拦截】DataAddException: 请求方法 {}, 请求路径 {}",((DataAddException)e).getCode(),((DataAddException)e).getMessage());
return CommonResult.failed(ResultCode.DATA_ADD_ERROR);
}else if (e instanceof DataMatchException){
log.error("【全局异常拦截】DataMatchException: 请求方法 {}, 请求路径 {}",((DataMatchException)e).getCode(),((DataMatchException)e).getMessage());
return CommonResult.failed(ResultCode.USERNAME_OR_PASSWORD_ERROR);
} else {
log.error("服务器内部出错{}",e);
return CommonResult.failed(ResultCode.FAILED);
}
}
}
自定义数据添加异常类
public class DataAddException extends RuntimeException {
private String code;
private String message;
public DataAddException(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
自定义数据匹配异常类
public class DataMatchException extends RuntimeException {
private String code;
private String message;
public DataMatchException(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
以上是实现该功能的所有类,当然进行密码加密处理的类只涉及service层以及启动类,其他类为基本类,如果你只想了解怎么进行加密处理存入数据库以及怎么登陆就看看service层就行。
总结
到此这篇关于springboot实现注册的加密与登录的解密功能的文章就介绍到这了,更多相关springboot实现注册的加密与登录的解密内容请搜索考高分网以前的文章或继续浏览下面的相关文章希望大家以后多多支持考高分网!



