springboot实现注册加密与登录解密功能(demo)
前情提要:本demo是基于springboot+mybatis-plus实现加密,加密为主,全局异常处理,日志处理为辅,而登录密码加密是每个项目中必须要的,密码不可能明文存入数据,这样没有安全性。
涉及的功能,全局异常处理,日志处理,mybatis-plus实现与数据库的交互,密码加密,restful风格
涉及的工具:IDEA,postman,sqlyog(navicat)
1.首先我们直接看效果吧,如果你不满意,也就没必要看了
如果这正是你想要的效果呢,那你可以继续看下面的内容了
2.首先,我们看下pom.xml文件
以下依赖为所需的主要依赖
4.0.0 org.springframework.boot spring-boot-starter-parent 2.2.4.RELEASE com.jgsu springboot_rsa_encryption 0.0.1-SNAPSHOT springboot_encryption DemoprojectforSpringBoot 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-devtools true mysql mysql-connector-java 5.1.47 org.projectlombok lombok 1.16.20 com.alibaba druid-spring-boot-starter 1.1.10 com.baomidou mybatis-plus-boot-starter 3.2.0 org.springframework.boot spring-boot-starter-security 2.1.6.RELEASE com.alibaba fastjson 1.2.51 org.springframework.boot spring-boot-maven-plugin
3.创建启动类SpringbootEncryptionApplication
importorg.mybatis.spring.annotation.MapperScan; importorg.springframework.boot.SpringApplication; importorg.springframework.boot.autoconfigure.SpringBootApplication; importorg.springframework.context.annotation.Bean; importorg.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; @SpringBootApplication @MapperScan("com.jgsu.mapper") publicclassSpringbootEncryptionApplication{ publicstaticvoidmain(String[]args){ SpringApplication.run(SpringbootEncryptionApplication.class,args); } /** *将加密工具类加入IOC容器中,便于加密 **/ @Bean publicBCryptPasswordEncoderencoder(){ returnnewBCryptPasswordEncoder(); } }
4.实体类
这里只有用户名和密码(其他数据自己可扩展)
@Data @AllArgsConstructor @NoArgsConstructor @TableName("user") publicclassUser{ @TableId(value="id",type=IdType.AUTO) privateintid; privateStringusername; privateStringpassword; }
5.service层(业务层)
importcom.baomidou.mybatisplus.core.conditions.query.QueryWrapper; importcom.jgsu.entity.User; importcom.jgsu.exception.DataAddException; importcom.jgsu.exception.DataMatchException; importcom.jgsu.mapper.UserMapper; importcom.jgsu.service.UserService; importlombok.extern.slf4j.Slf4j; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; importorg.springframework.stereotype.Service; @Slf4j @Service publicclassUserServiceImplimplementsUserService{ @Autowired UserMapperuserMapper; //数据加密,在启动类中已经注入进IOC容器中 @Autowired privateBCryptPasswordEncoderencoder; @Override publicUseruserLogin(Stringusername,Stringpassword){ //mybatis-plus的条件构造器,这里实现根据username查询 QueryWrapperwrapper=newQueryWrapper (); wrapper.eq("username",username); UseruserLogin=userMapper.selectOne(wrapper); /** *encoder.matches(password,userLogin.getPassword(),实现输入的密码与数据库中的密码进 *行匹配,如果匹配成功则返回匹配的数据给controller层,如果失败则抛异常。 *为什么没盐,没有解密了?因为这个已经被CryptPasswordEncoder封装好了, *在encoder.matches()方进行解密匹配完全帮你封装好了,所以不必考虑, *只需要将前端传入的密码与数据库中加密后的密码进行匹配就行。 ***/ if(userLogin!=null&&encoder.matches(password,userLogin.getPassword())){ log.info("用户{},登录成功",username); returnuserLogin; }else{ log.error("用户名或密码错误"); thrownewDataMatchException("405","用户名或密码错误"); } } @Override publicUseruserRegister(Stringusername,Stringpassword){ Useruser=newUser(); user.setId(user.getId()); user.setUsername(username); user.setPassword(encoder.encode(password)); inti=userMapper.insert(user); if(i==1){ log.info("用户{}注册成功",username); returnuser; }else{ log.error("服务器发生异常,注册失败"); thrownewDataAddException("403","注册失败"); } } }
6.mapper层
如果不了解,可以建议去看看mybatis-plus官方文档
importcom.baomidou.mybatisplus.core.mapper.BaseMapper; importcom.jgsu.entity.User; importorg.springframework.stereotype.Repository; @Repository publicinterfaceUserMapperextendsBaseMapper{ }
7.controller层
importcom.jgsu.entity.User; importcom.jgsu.service.UserService; importcom.jgsu.utils.CommonResult; importcom.jgsu.utils.ResultCode; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.web.bind.annotation.GetMapping; importorg.springframework.web.bind.annotation.PathVariable; importorg.springframework.web.bind.annotation.RequestMapping; importorg.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/user") publicclassUserController{ @Autowired UserServiceuserService; //注册,基于restful风格 @GetMapping("/register/{username}/{password}") publicCommonResultregister(@PathVariable("username")Stringusername,@PathVariable("password")Stringpassword){ Useruser=userService.userRegister(username,password); if(user!=null){ returnCommonResult.success(ResultCode.SUCCESS); }else{ returnCommonResult.failed(ResultCode.FAILED); } } //登录,基于restful风格 @GetMapping("/login/{username}/{password}") publicCommonResultlogin(@PathVariable("username")Stringusername,@PathVariable("password")Stringpassword){ UseruserLogin=userService.userLogin(username,password); if(userLogin!=null){ returnCommonResult.success(ResultCode.SUCCESS); }else{ returnCommonResult.failed(ResultCode.USERNAME_OR_PASSWORD_ERROR); } } }
8.配置类(返回json数据的类)
封装错误码的接口
publicinterfaceIErrorCode{ longgetState(); StringgetMessage(); }
枚举了一些常用API操作码
publicenumResultCodeimplementsIErrorCode{ /** *成功 */ SUCCESS(200,"ok"), /** *失败 */ FAILED(500,"servererror"), /** *验证过期 */ 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"); privatelongstate; privateStringstateInfo; ResultCode(longstate,StringstateInfo){ this.state=state; this.stateInfo=stateInfo; } @Override publiclonggetState(){ returnstate; } @Override publicStringgetMessage(){ returnstateInfo; } }
通用返回对象
publicclassCommonResult{ privatelongstate; privateStringstateInfo; privateTdata; publicCommonResult(){ } publicCommonResult(longstate,StringstateInfo,Tdata){ this.state=state; this.stateInfo=stateInfo; this.data=data; } publicCommonResult(longstate,StringstateInfo){ this.state=state; this.stateInfo=stateInfo; } /** *成功返回结果 * *@paramdata获取的数据 */ publicstatic CommonResult success(Tdata){ returnnewCommonResult (ResultCode.SUCCESS.getState(),ResultCode.SUCCESS.getMessage(),data); } /** *成功返回结果 *@paramdata获取的数据 *@parammessage提示信息 *@return */ publicstatic CommonResult success(Tdata,Stringmessage){ returnnewCommonResult (ResultCode.SUCCESS.getState(),message,data); } /** *失败返回结果 *@paramerrorCode错误码 */ publicstatic CommonResult failed(IErrorCodeerrorCode){ returnnewCommonResult (errorCode.getState(),errorCode.getMessage(),null); } /** *失败返回结果 *@parammessage提示信息 */ publicstatic CommonResult failed(Stringmessage){ returnnewCommonResult (ResultCode.FAILED.getState(),message,null); } /** *失败返回结果 *@paramcode *@parammessage */ publicstatic CommonResult failed(intcode,Stringmessage){ returnfailed(ResultCode.FAILED); } /** *参数验证失败返回结果 */ publicstatic CommonResult validateFailed(){ returnfailed(ResultCode.VALIDATE_FAILED); } /** *参数验证失败返回结果 *@parammessage提示信息 */ publicstatic CommonResult validateFailed(Stringmessage){ returnnewCommonResult (ResultCode.VALIDATE_FAILED.getState(),message,null); } /** *未登录返回结果 */ publicstatic CommonResult unauthorized(Tdata){ returnnewCommonResult (ResultCode.UNAUTHORIZED.getState(),ResultCode.UNAUTHORIZED.getMessage(),data); } /** *未授权返回结果 */ publicstatic CommonResult forbidden(Tdata){ returnnewCommonResult (ResultCode.FORBIDDEN.getState(),ResultCode.FORBIDDEN.getMessage(),data); } publiclonggetState(){ returnstate; } publicvoidsetState(longstate){ this.state=state; } publicStringgetStateInfo(){ returnstateInfo; } publicvoidsetStateInfo(StringstateInfo){ this.stateInfo=stateInfo; } publicTgetData(){ returndata; } publicvoidsetData(Tdata){ this.data=data; } }
9.异常类
全局异常拦截类
@Slf4j @ControllerAdvice @ResponseBody publicclassGlobalExceptionHander{ @ExceptionHandler(value=Exception.class) publicCommonResulthandlerException(Exceptione){ if(einstanceofDataAddException){ log.error("【全局异常拦截】DataAddException:请求方法{},请求路径{}",((DataAddException)e).getCode(),((DataAddException)e).getMessage()); returnCommonResult.failed(ResultCode.DATA_ADD_ERROR); }elseif(einstanceofDataMatchException){ log.error("【全局异常拦截】DataMatchException:请求方法{},请求路径{}",((DataMatchException)e).getCode(),((DataMatchException)e).getMessage()); returnCommonResult.failed(ResultCode.USERNAME_OR_PASSWORD_ERROR); }else{ log.error("服务器内部出错{}",e); returnCommonResult.failed(ResultCode.FAILED); } } }
自定义数据添加异常类
publicclassDataAddExceptionextendsRuntimeException{ privateStringcode; privateStringmessage; publicDataAddException(Stringcode,Stringmessage){ this.code=code; this.message=message; } publicStringgetCode(){ returncode; } publicvoidsetCode(Stringcode){ this.code=code; } @Override publicStringgetMessage(){ returnmessage; } publicvoidsetMessage(Stringmessage){ this.message=message; } }
自定义数据匹配异常类
publicclassDataMatchExceptionextendsRuntimeException{ privateStringcode; privateStringmessage; publicDataMatchException(Stringcode,Stringmessage){ this.code=code; this.message=message; } publicStringgetCode(){ returncode; } publicvoidsetCode(Stringcode){ this.code=code; } @Override publicStringgetMessage(){ returnmessage; } publicvoidsetMessage(Stringmessage){ this.message=message; } }
以上是实现该功能的所有类,当然进行密码加密处理的类只涉及service层以及启动类,其他类为基本类,如果你只想了解怎么进行加密处理存入数据库以及怎么登陆就看看service层就行。
总结
到此这篇关于springboot实现注册的加密与登录的解密功能的文章就介绍到这了,更多相关springboot实现注册的加密与登录的解密内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。