公司做铸造的招聘网站都有哪些,深圳网站建设公司联系方式,品牌建设方案和思路,内容聚合网站开发教程文章目录 1.数据库表设计1.IDEA连接数据库2.修改application.yml中数据库的名称为seckill3.IDEA创建数据库seckill4.创建数据表 seckill_user5.密码加密分析1.传统方式#xff08;不安全#xff09;2.改进方式#xff08;两次加密加盐#xff09; 2.密码加密功能实现1.pom.… 文章目录 1.数据库表设计1.IDEA连接数据库2.修改application.yml中数据库的名称为seckill3.IDEA创建数据库seckill4.创建数据表 seckill_user5.密码加密分析1.传统方式不安全2.改进方式两次加密加盐 2.密码加密功能实现1.pom.xml添加md5加密的依赖刷新maven2.编写工具类MD5Util.java完成加密3.测试1.引入jupiter 5.7.2依赖2.测试方法 3.编写实体类映射表1.创建pojo目录2.User.java 4.创建Mapper接口和Mapper.xml1.创建UserMapper.java2.创建UserMapper.xml 5.响应信息类1.创建vo目录2.RespBeanEnum.java 响应信息枚举类3.RespBean.java 响应信息的Bean 6.编写接受登录信息的vo以及手机号校验工具类1.LoginVo.java2.ValidatorUtil.java 7.编写service层1.UserService.java2.UserServiceImpl.java 8.编写controller层1.引入校验的依赖2.LoginController.java3.引入静态资源和模板页4.解析前端登录1.点击登录调用login2.将密码加密加盐之后向后端 /login/doLogin 发送请求 5.测试访问首页1.首先检查资源是否到了target目录如果没到需要maven重新编译2.测试访问 http://localhost:9092/seckill/login/toLogin 6.前端区分多环境1.可以看到前端请求时使用的/其实只是本机的服务发现也就是http://localhost:9092/所以需要区分多环境2.首先新增一个配置类 GlobalControllerAdvice.java 全局控制器通知用于向前端传递全局变量3.在application.yml和application-prod.yml编写baseUrl区分多环境4.login.html 读取baseUrl1.在script标签内添加一行代码使其能够解析Thymeleaf2.修改请求格式为 baseUrl 资源路径 7.在数据库添加一条记录可以模拟用户登录1.假设密码是admin在前端输出一下第一次加密加盐的结果2.使用后端的工具类也来加密一下比对结果发现结果一致3.在第二次加密的时候重新设置一个不同的盐为niubi666模拟不同用户4.将结果放到数据库中5.此时的用户名和密码 8.编写登录的controller并测试1.LoginController.java2.测试登录成功 1.数据库表设计
1.IDEA连接数据库
2.修改application.yml中数据库的名称为seckill
3.IDEA创建数据库seckill 4.创建数据表 seckill_user
DROP TABLE IF EXISTS seckill_user;
CREATE TABLE seckill_user
(id BIGINT(20) NOT NULL COMMENT 用户 ID, 设为主键, 唯一 手机号,nickname VARCHAR(255) NOT NULL DEFAULT ,password VARCHAR(32) NOT NULL DEFAULT COMMENT MD5(MD5(pass 明文固定salt)salt),slat VARCHAR(10) NOT NULL DEFAULT ,head VARCHAR(128) NOT NULL DEFAULT COMMENT 头像,register_date DATETIME DEFAULT NULL COMMENT 注册时间,last_login_date DATETIME DEFAULT NULL COMMENT 最后一次登录时间,login_count INT(11) DEFAULT 0 COMMENT 登录次数,PRIMARY KEY (id)
) ENGINE INNODB DEFAULT CHARSET utf8mb4;
select * from seckill_user;5.密码加密分析
1.传统方式不安全 2.改进方式两次加密加盐 2.密码加密功能实现
1.pom.xml添加md5加密的依赖刷新maven !--md5 依赖--dependencygroupIdcommons-codec/groupIdartifactIdcommons-codec/artifactIdversion1.15/version/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-lang3/artifactIdversion3.11/version/dependency
2.编写工具类MD5Util.java完成加密
package com.sxs.seckill.utils;import org.apache.commons.codec.digest.DigestUtils;/*** Description: MD5加密工具类** Author sun* Create 2024/5/5 14:23* Version 1.0*/
public class MD5Util {/*** 将一个字符串转换为MD5* param src* return*/public static String md5(String src) {return DigestUtils.md5Hex(src);}// 固定的saltpublic static final String SALT dgeb2g4t;// 第一次加密加盐public static String inputPassToMidPass(String inputPass) {// 加盐String str SALT.charAt(0) inputPass SALT.charAt(6);return md5(str);}/*** 第二次加密加盐* param midPass* param salt* return*/public static String midPassToDBPass(String midPass, String salt) {String str salt.charAt(0) midPass salt.charAt(5);return md5(str);}/*** 两次加密* param input* param saltDB* return*/public static String inputPassToDBPass(String input, String saltDB) {String midPass inputPassToMidPass(input);String dbPass midPassToDBPass(midPass, saltDB);return dbPass;}
}
3.测试
1.引入jupiter 5.7.2依赖 !-- jupiter测试 --dependencygroupIdorg.junit.jupiter/groupIdartifactIdjunit-jupiter-api/artifactIdversion5.7.2/versionscopecompile/scope/dependency2.测试方法
package com.sxs.seckill.utils;/*** Description: 测试MD5加密方法** Author sun* Create 2024/5/5 14:47* Version 1.0*/
public class MD5UtilTest {public static void main(String[] args) {String input 123456;System.out.println(第一次加密 MD5Util.inputPassToMidPass(input));System.out.println(第二次加密 MD5Util.midPassToDBPass(MD5Util.inputPassToMidPass(input), MD5Util.SALT));System.out.println(两次加密 MD5Util.inputPassToDBPass(input, MD5Util.SALT));}
} 3.编写实体类映射表
1.创建pojo目录 2.User.java
package com.sxs.seckill.pojo;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.io.Serializable;
import java.util.Date;/*** Description:** Author sun* Create 2024/5/5 14:59* Version 1.0*/
Data
TableName(seckill_user) // 指定表名
public class User implements Serializable { // 实现序列化接口private static final long serialVersionUID 1L;/*** 用户 ID是手机号码*/TableId(value id, type IdType.ASSIGN_ID) // 指定主键IdType.ASSIGN_ID表示自己指定ID,不自增private Long id;private String nickname;/*** MD5(MD5(pass 明文固定 salt)salt)*/private String password;private String slat;/*** 头像*/private String head;/*** 注册时间*/private Date registerDate;/*** 最后一次登录时间*/private Date lastLoginDate;/*** 登录次数*/private Integer loginCount;
}4.创建Mapper接口和Mapper.xml
1.创建UserMapper.java
package com.sxs.seckill.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sxs.seckill.pojo.User;/*** Description:** Author sun* Create 2024/5/5 15:04* Version 1.0*/
public interface UserMapper extends BaseMapperUser {
}
2.创建UserMapper.xml
?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtdmapper namespacecom.sxs.seckill.mapper.UserMapper!-- 通用查询映射结果 --resultMap idBaseResultMap typecom.sxs.seckill.pojo.Userid columnid propertyid/result columnnickname propertynickname/result columnpassword propertypassword/result columnslat propertyslat/result columnhead propertyhead/result columnregister_date propertyregisterDate/result columnlast_login_date propertylastLoginDate/result columnlogin_count propertyloginCount//resultMap
/mapper5.响应信息类
1.创建vo目录 2.RespBeanEnum.java 响应信息枚举类
package com.sxs.seckill.vo;import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;/*** Description: 响应枚举类** Author sun* Create 2024/5/5 15:15* Version 1.0*/Getter
AllArgsConstructor
ToString
public enum RespBeanEnum {// 通用SUCCESS(200, SUCCESS),ERROR(500, 服务端异常),//登录模块LOGIN_ERROR(500210, 用户名或者密码错误),MOBILE_ERROR(500211, 手机号码格式不正确), BING_ERROR(500212, 参数绑定异常), MOBILE_NOT_EXIST(500213, 手机号码不存在), PASSWORD_UPDATE_FAIL(500214, 更新密码失败);// 响应码和响应信息private final Integer code;private final String message;}
3.RespBean.java 响应信息的Bean
package com.sxs.seckill.vo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** Description:** Author sun* Create 2024/5/5 15:32* Version 1.0*/
Data
NoArgsConstructor
AllArgsConstructor
public class RespBean {private long code;private String message;private Object obj;// 成功后public static RespBean success(Object obj) {return new RespBean(RespBeanEnum.SUCCESS.getCode(), RespBeanEnum.SUCCESS.getMessage(), obj);}public static RespBean success() {return new RespBean(RespBeanEnum.SUCCESS.getCode(), RespBeanEnum.SUCCESS.getMessage(), null);}// 失败各有不同public static RespBean error(RespBeanEnum respBeanEnum) {return new RespBean(respBeanEnum.getCode(), respBeanEnum.getMessage(), null);}public static RespBean error(RespBeanEnum respBeanEnum, Object obj) {return new RespBean(respBeanEnum.getCode(), respBeanEnum.getMessage(), obj);}
}6.编写接受登录信息的vo以及手机号校验工具类
1.LoginVo.java
package com.sxs.seckill.vo;/*** Description: 登录实体类** Author sun* Create 2024/5/5 15:43* Version 1.0*/
public class LoginVo {private String mobile;private String password;
}
2.ValidatorUtil.java
package com.sxs.seckill.utils;import org.junit.jupiter.api.Test;/*** Description: 校验工具类** Author sun* Create 2024/5/5 15:45* Version 1.0*/
public class ValidatorUtil {/*** 校验手机号是否有效* param phoneNumber 手机号* return 如果手机号有效返回 true否则返回 false*/public static boolean isMobile(String phoneNumber) {// 中国大陆的手机号码正则表达式要求是11位数字以1开头第二位是3-9后面是任意数字共11位String regex ^1[3-9]\\d{9}$;return phoneNumber.matches(regex);}// 测试Testpublic void t1() {System.out.println(isMobile(12345678901));System.out.println(isMobile(1234567890));// 正确的System.out.println(isMobile(13604969873));}
} 7.编写service层
1.UserService.java
package com.sxs.seckill.service;import com.baomidou.mybatisplus.extension.service.IService;
import com.sxs.seckill.pojo.User;
import com.sxs.seckill.vo.LoginVo;
import com.sxs.seckill.vo.RespBean;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** Description:** Author sun* Create 2024/5/5 15:58* Version 1.0*/
public interface UserService extends IServiceUser {/*** 用户登录校验* param loginVo* param request* param response* return*/RespBean doLogin(LoginVo loginVo, HttpServletRequest request, HttpServletResponse response);
}
2.UserServiceImpl.java
package com.sxs.seckill.service.impl;import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sxs.seckill.mapper.UserMapper;
import com.sxs.seckill.pojo.User;
import com.sxs.seckill.service.UserService;
import com.sxs.seckill.utils.MD5Util;
import com.sxs.seckill.utils.ValidatorUtil;
import com.sxs.seckill.vo.LoginVo;
import com.sxs.seckill.vo.RespBean;
import com.sxs.seckill.vo.RespBeanEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;/*** Description:** Author sun* Create 2024/5/5 15:59* Version 1.0*/
Service
public class UserServiceImpl extends ServiceImplUserMapper, User implements UserService {Resourceprivate UserMapper userMapper;Overridepublic RespBean doLogin(LoginVo loginVo, HttpServletRequest request, HttpServletResponse response) {// 获取用户输入的手机号和密码此时的密码已经是midPassString mobile loginVo.getMobile();String password loginVo.getPassword();// 判断手机号和密码是否为空if (StringUtils.isBlank(mobile) || StringUtils.isBlank(password)) {return RespBean.error(RespBeanEnum.LOGIN_ERROR);}// 校验手机号是否正确if (!ValidatorUtil.isMobile(mobile)) {return RespBean.error(RespBeanEnum.MOBILE_ERROR);}// 根据手机号查询用户User user userMapper.selectById(mobile);// 判断用户是否为空if (null user) {return RespBean.error(RespBeanEnum.LOGIN_ERROR);}// 判断密码是否正确if (!MD5Util.midPassToDBPass(password, user.getSlat()).equals(user.getPassword())) {return RespBean.error(RespBeanEnum.LOGIN_ERROR);}// 返回成功return RespBean.success();}
}
8.编写controller层
1.引入校验的依赖 !--validation 参数校验--dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-validation/artifactIdversion2.4.5/version/dependency2.LoginController.java
package com.sxs.seckill.controller;import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;/*** Description:** Author sun* Create 2024/5/5 16:41* Version 1.0*/
Slf4j
Controller
RequestMapping(/login)
public class LoginController {/*** 访问/login/toLogin会跳转到templates/login.html* return*/RequestMapping(/toLogin)public String toLogin() {return login;}}
3.引入静态资源和模板页 4.解析前端登录
1.点击登录调用login 2.将密码加密加盐之后向后端 /login/doLogin 发送请求 5.测试访问首页
1.首先检查资源是否到了target目录如果没到需要maven重新编译 2.测试访问 http://localhost:9092/seckill/login/toLogin 6.前端区分多环境
1.可以看到前端请求时使用的/其实只是本机的服务发现也就是http://localhost:9092/所以需要区分多环境 2.首先新增一个配置类 GlobalControllerAdvice.java 全局控制器通知用于向前端传递全局变量
package com.sxs.seckill.config;import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ModelAttribute;/*** Description: 全局控制器通知用于向前端传递全局变量** Author sun* Create 2024/5/5 17:08* Version 1.0*/
ControllerAdvice
public class GlobalControllerAdvice {// 从配置文件中读取baseUrl从而使前端可以区分多环境Value(${baseurl})private String baseurl;ModelAttribute(baseUrl)public String baseUrl() {// 这里可以根据环境变量或其他逻辑来动态确定 URLreturn baseurl;}
}
3.在application.yml和application-prod.yml编写baseUrl区分多环境 4.login.html 读取baseUrl
1.在script标签内添加一行代码使其能够解析Thymeleaf
th:inlinejavascript2.修改请求格式为 baseUrl 资源路径 7.在数据库添加一条记录可以模拟用户登录
1.假设密码是admin在前端输出一下第一次加密加盐的结果 2.使用后端的工具类也来加密一下比对结果发现结果一致 3.在第二次加密的时候重新设置一个不同的盐为niubi666模拟不同用户 4.将结果放到数据库中 5.此时的用户名和密码
19588888888195八个八admin
8.编写登录的controller并测试
1.LoginController.java ResponseBodyRequestMapping(/doLogin)public RespBean doLogin(LoginVo loginVo, HttpServletRequest request, HttpServletResponse response) {RespBean respBean userService.doLogin(loginVo, request, response);// 返回return respBean;}
2.测试登录成功