這篇文章將為大家詳細(xì)講解有關(guān)springboot如何實(shí)現(xiàn)注冊加密與登錄解密功能,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
創(chuàng)新互聯(lián)是一家專注于成都網(wǎng)站建設(shè)、做網(wǎng)站與策劃設(shè)計(jì),永定網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10余年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:永定等地區(qū)。永定做網(wǎng)站價(jià)格咨詢:18982081108
前情提要:本demo是基于springboot+mybatis-plus實(shí)現(xiàn)加密,加密為主,全局異常處理,日志處理為輔,而登錄密碼加密是每個(gè)項(xiàng)目中必須要的,密碼不可能明文存入數(shù)據(jù),這樣沒有安全性。
涉及的功能,全局異常處理,日志處理,mybatis-plus實(shí)現(xiàn)與數(shù)據(jù)庫的交互,密碼加密,restful風(fēng)格
涉及的工具:IDEA,postman,sqlyog(navicat)
1. 首先我們直接看效果吧,如果你不滿意,也就沒必要看了
如果這正是你想要的效果呢,那你可以繼續(xù)看下面的內(nèi)容了
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 Demo project for Spring Boot 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. 創(chuàng)建啟動(dòng)類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); } /** * 將加密工具類加入IOC容器中,便于加密 * */ @Bean public BCryptPasswordEncoder encoder() { return new BCryptPasswordEncoder(); } }
4.實(shí)體類
這里只有用戶名和密碼(其他數(shù)據(jù)自己可擴(kuò)展)
@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層(業(yè)務(wù)層)
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; // 數(shù)據(jù)加密,在啟動(dòng)類中已經(jīng)注入進(jìn)IOC容器中 @Autowired private BCryptPasswordEncoder encoder; @Override public User userLogin(String username,String password) { // mybatis-plus的條件構(gòu)造器,這里實(shí)現(xiàn)根據(jù)username查詢 QueryWrapperwrapper = new QueryWrapper (); wrapper.eq("username", username); User userLogin = userMapper.selectOne(wrapper); /** * encoder.matches(password, userLogin.getPassword(),實(shí)現(xiàn)輸入的密碼與數(shù)據(jù)庫中的密碼進(jìn) * 行匹配,如果匹配成功則返回匹配的數(shù)據(jù)給controller層,如果失敗則拋異常。 * 為什么沒鹽,沒有解密了?因?yàn)檫@個(gè)已經(jīng)被CryptPasswordEncoder封裝好了, * 在encoder.matches()方進(jìn)行解密匹配完全幫你封裝好了,所以不必考慮, * 只需要將前端傳入的密碼與數(shù)據(jù)庫中加密后的密碼進(jìn)行匹配就行。 * **/ if (userLogin != null && encoder.matches(password, userLogin.getPassword())) { log.info("用戶{},登錄成功",username); return userLogin; } else { log.error("用戶名或密碼錯(cuò)誤"); throw new DataMatchException("405", "用戶名或密碼錯(cuò)誤"); } } @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(" 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風(fēng)格 @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風(fēng)格 @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數(shù)據(jù)的類)
封裝錯(cuò)誤碼的接口
public interface IErrorCode { long getState(); String getMessage(); }枚舉了一些常用API操作碼
public enum ResultCode implements IErrorCode { /** * 成功 */ SUCCESS(200, "ok"), /** * 失敗 */ FAILED(500, "server error"), /** * 驗(yàn)證過期 */ VALIDATE_FAILED(404, "undefined"), /** * 未登錄 */ UNAUTHORIZED(401, "未登錄"), /** * 用戶名或密碼錯(cuò)誤 */ USERNAME_OR_PASSWORD_ERROR(405, "用戶名或密碼錯(cuò)誤"), /** * 數(shù)據(jù)查詢錯(cuò)誤 */ DATA_Not_Exist_ERROR(603, "數(shù)據(jù)不存在"), /** * 數(shù)據(jù)添加出現(xiàn)問題 */ DATA_ADD_ERROR(604, "數(shù)據(jù)添加異常"), /** * 文件 */ FILE_ERROR(605, "上傳文件出現(xiàn)錯(cuò)誤"), /** * 數(shù)據(jù)查詢出現(xiàn)問題 */ IMAGE_ERROR(606, "圖片處理出現(xiàn)錯(cuò)誤"), /** * 權(quán)限不夠 */ 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; } /** * 成功返回結(jié)果 * * @param data 獲取的數(shù)據(jù) */ public static CommonResult success(T data) { return new CommonResult (ResultCode.SUCCESS.getState(), ResultCode.SUCCESS.getMessage(), data); } /** * 成功返回結(jié)果 * @param data 獲取的數(shù)據(jù) * @param message 提示信息 * @return */ public static CommonResult success(T data, String message) { return new CommonResult (ResultCode.SUCCESS.getState(), message, data); } /** * 失敗返回結(jié)果 * @param errorCode 錯(cuò)誤碼 */ public static CommonResult failed(IErrorCode errorCode) { return new CommonResult (errorCode.getState(), errorCode.getMessage(), null); } /** * 失敗返回結(jié)果 * @param message 提示信息 */ public static CommonResult failed(String message) { return new CommonResult (ResultCode.FAILED.getState(), message, null); } /** * 失敗返回結(jié)果 * @param code * @param message */ public static CommonResult failed(int code, String message) { return failed(ResultCode.FAILED); } /** * 參數(shù)驗(yàn)證失敗返回結(jié)果 */ public static CommonResult validateFailed() { return failed(ResultCode.VALIDATE_FAILED); } /** * 參數(shù)驗(yàn)證失敗返回結(jié)果 * @param message 提示信息 */ public static CommonResult validateFailed(String message) { return new CommonResult (ResultCode.VALIDATE_FAILED.getState(), message, null); } /** * 未登錄返回結(jié)果 */ public static CommonResult unauthorized(T data) { return new CommonResult (ResultCode.UNAUTHORIZED.getState(), ResultCode.UNAUTHORIZED.getMessage(), data); } /** * 未授權(quán)返回結(jié)果 */ 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("服務(wù)器內(nèi)部出錯(cuò){}",e); return CommonResult.failed(ResultCode.FAILED); } } }自定義數(shù)據(jù)添加異常類
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; } }
自定義數(shù)據(jù)匹配異常類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; } }springboot是什么
springboot一種全新的編程規(guī)范,其設(shè)計(jì)目的是用來簡化新Spring應(yīng)用的初始搭建以及開發(fā)過程,SpringBoot也是一個(gè)服務(wù)于框架的框架,服務(wù)范圍是簡化配置文件。
關(guān)于“springboot如何實(shí)現(xiàn)注冊加密與登錄解密功能”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯(cuò),請把它分享出去讓更多的人看到。
當(dāng)前題目:springboot如何實(shí)現(xiàn)注冊加密與登錄解密功能
新聞來源:http://weahome.cn/article/gjdcgi.html