书接上回,上一篇测试通过,这一篇开始讲解注册和登录逻辑
注册需求分析
- 用户在前端输入账户和密码、以及校验码(to do)
- 校验用户的账户、密码、校验码是否符合要求
- 非空
- 账户长度不小于4位
- 密码不小于8位
- 账号不能重复
- 账户不包含特殊字符
- 密码和校验密码相同
- 对密码进行加密(密码千万不能直接以明文存储到数据库)
- 向数据库插入用户数据
写注册代码
- 先接口,方法名,参数,返回值。在UserService里写
用户注册需要接收哪些参数:账户、密码、验证密码,返回值是插入之后生成的id,所以用long类型
long userRegister(String userAccount,String userPassword,String checkPassword);
- 写方法的具体实现:光标选中userRegister,alt+enter,选择Implement,就自动跳到实现类里面
- 在这里我们先去maven repository找一个很好用的库,是一个帮助我们判断字符串的工具库
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
- 然后就可以开始写代码了:
package com.kplusone.usercenter.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kplusone.usercenter.constant.UserConstant;
import com.kplusone.usercenter.model.domain.User;
import com.kplusone.usercenter.service.UserService;
import com.kplusone.usercenter.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author 13654
* @description 针对表【user(用户)】的数据库操作Service实现
* @createDate 2022-05-02 22:31:01
*/
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
implements UserService{
@Resource
private UserMapper userMapper;
/**
* 盐值,混淆密码
*/
private static final String SALT = "kplusone";
@Override
public long userRegister(String userAccount, String userPassword, String checkPassword) {
//1.校验
if(StringUtils.isAnyBlank(userAccount,userPassword,checkPassword)){
return -1;
}
if(userAccount.length()<4){
return -1;
}
if(userPassword.length() < 8 || checkPassword.length() < 8){
return -1;
}
//2.账户不能包含特殊字符
String validPattern = "[`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]";
Matcher matcher = Pattern.compile(validPattern).matcher(userAccount);
if(matcher.find()){
return -1;
}
//3.密码和校验密码相同
if(!userPassword.equals(checkPassword)){
return -1;
}
//4.账户不能重复
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("userAccount",userAccount);
long count = this.count(queryWrapper);
if(count > 0){
return -1;
}
//5.加密
String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
//6.插入数据
User user = new User();
user.setUserAccount(userAccount);
user.setUserPassword(encryptPassword);
boolean saveResult = this.save(user);
if(!saveResult){
return -1;
}
return user.getId();
}
@Override
public User userLogin(String userAccount, String userPassword, HttpServletRequest request) {
//1.校验
if(StringUtils.isAnyBlank(userAccount,userPassword)){
return null;
}
if(userAccount.length()<4){
return null;
}
if(userPassword.length() < 8){
return null;
}
//2.账户不能包含特殊字符
String validPattern = "[`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]";
Matcher matcher = Pattern.compile(validPattern).matcher(userAccount);
if(matcher.find()){
return null;
}
//5.加密
String encryptPassword = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
//查询用户是否存在
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("userAccount",userAccount);
queryWrapper.eq("userPassword",encryptPassword);
User user = userMapper.selectOne(queryWrapper);
if (user == null){
log.info("user login failed,userAccount cannot match userPassword");
return null;
}
//用户脱敏
User safetyUser = getSafetyUser(user);
//记录用户的登录态
request.getSession().setAttribute(UserConstant.USER_LOGIN_STATE,safetyUser);
return safetyUser;
}
@Override
public User getSafetyUser(User originUser){
User safetyuser = new User();
safetyuser.setId(originUser.getId());
safetyuser.setUsername(originUser.getUsername());
safetyuser.setUserAccount(originUser.getUserAccount());
safetyuser.setAvatarUrl(originUser.getAvatarUrl());
safetyuser.setGender(originUser.getGender());
safetyuser.setUserRole(originUser.getUserRole());
safetyuser.setPhone(originUser.getPhone());
safetyuser.setEmail(originUser.getEmail());
safetyuser.setUserStatus(originUser.getUserStatus());
safetyuser.setCreateTime(originUser.getCreateTime());
return safetyuser;
}
}
因为是后续补的博客,这里面先只看注册的实现逻辑,登录之后再说。
- 写完一点就测试一点
光标放在方法名上,alt+enter ,选择test,点击OK
package com.kplusone.usercenter.service;
import com.kplusone.usercenter.model.domain.User;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
/**
* 用户服务测试
*
* @author kplusone
*/
@SpringBootTest
class UserServiceTest {
@Resource
private UserService userService;
@Test
public void testAddUser(){
User user = new User();
user.setUsername("kplusone");
user.setUserAccount("123");
user.setAvatarUrl("https://profile.csdnimg.cn/1/0/0/0_weixin_44063572");
user.setUserPassword("xxx");
user.setPhone("123");
user.setEmail("456");
user.setGender(0);
boolean save = userService.save(user);
System.out.println(user.getId());//虽然没有设置Id,但是mybatis会将数据库自动生成的id填进去
Assertions.assertTrue(save);
}
@Test
void userRegister() {
//非空
String userAccount = "kplusone";
String userPassword = "";
String checkPassword = "123456789";
long result = userService.userRegister(userAccount, userPassword, checkPassword);
Assertions.assertEquals(-1,result);
//账户长度不小于4位
userAccount = "ko";
userPassword = "123456789";
checkPassword = "123456789";
result = userService.userRegister(userAccount, userPassword, checkPassword);
Assertions.assertEquals(-1,result);
//密码不小于8位
userAccount = "kplusone";
userPassword = "123";
checkPassword = "123";
result = userService.userRegister(userAccount, userPassword, checkPassword);
Assertions.assertEquals(-1,result);
//账户不能重复
// userAccount = "123456";
// userPassword = "123456789";
// checkPassword = "123456789";
// result = userService.userRegister(userAccount, userPassword, checkPassword);
// Assertions.assertEquals(-1,result);
//密码和校验密码相同
userAccount = "kplusone";
userPassword = "123456789";
checkPassword = "1234567899";
result = userService.userRegister(userAccount, userPassword, checkPassword);
Assertions.assertEquals(-1,result);
//账户包含特殊字符
userAccount = "kplusone*";
userPassword = "123456789";
checkPassword = "123456789";
result = userService.userRegister(userAccount, userPassword, checkPassword);
Assertions.assertEquals(-1,result);
//注册成功
userAccount = "kplusone";
userPassword = "123456789";
checkPassword = "123456789";
result = userService.userRegister(userAccount, userPassword, checkPassword);
Assertions.assertTrue(result>0);
}
}
这个代码运行是成功的,但是在写的过程也出现过bug。记录一下:
是因为正则表达式写错了,然后又百度了一个就对了。提一嘴:在学习编程过程中,有很多类似正则表达式这种随学随用的知识,总是让人不痛不痒,比如:Linux、git这些,这种知识最好的方法就是整理一遍,下次就可以直接查,所以这里挖一个坑,以后再填。常常把软件开发作为是造一艘航空母舰,里面涉及到的知识有前后端,测试,部署,运维等等,再挖细节的技术栈那更是一辈子都学不完,那我们的心态就应该是:先学最小必要知识,然后实践,再实践的过程不断拓宽自己的广度和深度,这个时候就得用博客记录自己的所学,还有一点更重要的是:虽然学不完所有的知识,但是对于每个技术是解决什么问题,它处于整个项目什么位置,心中有一个全局观会让我们在学习的过程中更加自然和舒服,一直保持一个愿意持续学习的心态。