流程
表设计
create table if not exists kanyuServer.user_db
(id bigint unsigned auto_increment comment '主键'primary key,phone varchar(11) not null comment '手机号码',password varchar(128) default '' null comment '密码,加密存储',user_name varchar(32) default '' null comment '昵称,默认是用户id',create_time timestamp default CURRENT_TIMESTAMP not null comment '创建时间',update_time timestamp default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',constraint uniqe_key_phoneunique (phone)
);
功能设计
用户注册功能
用户注册的流程如下
1,用户输入手机号和名称
2,后端校验是否注册过
3,数据库插入数据
代码
用户实体类
package com.kanyuServer.entity;import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;import java.io.Serializable;
import java.time.LocalDateTime;@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("user_db")
public class User implements Serializable {private static final long serialVersionUID = 1L;/*** 主键*/@TableId(value = "id", type = IdType.AUTO)private Long id;/*** 手机号码*/private String phone;/*** 密码,需加密存储*/private String password;/*** 昵称,默认是随机字符*/private String userName;/*** 创建时间*/private LocalDateTime createTime;/*** 更新时间*/private LocalDateTime updateTime;}
注册控制器
package com.kanyuServer.controller;import cn.hutool.json.JSON;
import com.kanyuServer.common.Result;
import com.kanyuServer.dto.RegisterForm;
import com.kanyuServer.entity.User;
import com.kanyuServer.service.LoginService;
import com.kanyuServer.service.RegisterService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import javax.servlet.http.HttpSession;/*** 登录控制器*/
@Slf4j
@RestController
@RequestMapping("/register")
public class RegisterController {@ResourceRegisterService registerService;@PostMapping("user")public Result sendCode(@RequestBody RegisterForm registerForm, HttpSession session) {//打印日志log.info("用户注册信息"+ registerForm.toString());Result result = registerService.register(registerForm,session);return result;}}
mapper
package com.kanyuServer.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.kanyuServer.entity.User;public interface UserMapper extends BaseMapper<User> {
}
service
package com.kanyuServer.service.impl;import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kanyuServer.common.Result;
import com.kanyuServer.dto.RegisterForm;
import com.kanyuServer.entity.User;
import com.kanyuServer.mapper.UserMapper;
import com.kanyuServer.service.LoginService;
import com.kanyuServer.service.RegisterService;
import com.kanyuServer.utils.Validate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.kanyuServer.utils.PasswordUtil;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;import static com.kanyuServer.constant.RedisConstants.LOGIN_CODE_KEY;
import static com.kanyuServer.constant.RedisConstants.LOGIN_CODE_TTL;
import static com.kanyuServer.constant.ResponseConstant.*;@Slf4j
@Service
public class RegistererviceImpl extends ServiceImpl<UserMapper, User> implements RegisterService {//引入redis工具类@Resourceprivate StringRedisTemplate stringRedisTemplate;@Overridepublic Result register(RegisterForm registerForm, HttpSession session) {// 1.校验手机号String phone = registerForm.getPhone();if (Validate.isPhoneInvalid(phone)) {// 2.如果不符合,返回错误信息return Result.fail("手机号格式错误!",400);}User user_query = query().eq("phone", phone).one();if (user_query!=null){return Result.fail("用户已注册过,请登录",400);}registerForm.setPassword(PasswordUtil.hashPassword(registerForm.getPassword()));User user = new User();user.setPassword(registerForm.getPassword());user.setUserName(registerForm.getUserName());user.setPhone(registerForm.getPhone());save(user);return Result.ok();}
}
用户登录功能
密码登录
@Overridepublic Result loginWithPassward(LoginForm loginForm, HttpSession session) {// 1.校验手机号String phone = loginForm.getPhone();if (Validate.isPhoneInvalid(phone)) {// 2.如果不符合,返回错误信息return Result.fail("手机号格式错误!",400);}User user = query().eq("phone", loginForm.getPhone()).one();if (user==null){//返回用户不存在 这里预期进入注册网页return Result.fail(USER_NOT_FOUND,USER_NOT_FOUNT_CODE);}//校验密码是否正确 这里直接对比原始的密码与加密的密码是否相同boolean flag = PasswordUtil.checkPassword(loginForm.getPassword(),user.getPassword());//不正确if (!flag){return Result.fail(USER_PASSWORD_NOT_CORRECT,USER_PASSWORD_NOT_CORRECT_CODE);}// 保存用户信息到 redis中// 随机生成token,作为登录令牌String token = UUID.randomUUID().toString(true);// 将User对象转为HashMap存储LoginForm loginForm1 = BeanUtil.copyProperties(user, LoginForm.class);System.out.println(loginForm1);log.info(loginForm1.toString());loginForm1.setCode("");Map<String, Object> userMap = BeanUtil.beanToMap(loginForm1, new HashMap<>(),CopyOptions.create().setIgnoreNullValue(true).setFieldValueEditor((fieldName, fieldValue) -> fieldValue.toString()));// 存储String tokenKey = LOGIN_USER_KEY + token;stringRedisTemplate.opsForHash().putAll(tokenKey, userMap);// 设置token有效期stringRedisTemplate.expire(tokenKey, LOGIN_USER_TTL, TimeUnit.MINUTES);Map<String,Object> result = new HashMap<>();result.put("token",token);result.put("user",user);//返回tokenreturn Result.ok(result);}
验证码登录
@Overridepublic Result loginWithCode(LoginForm loginForm, HttpSession session) {//校验手机号String phone = loginForm.getPhone();if (Validate.isPhoneInvalid(phone)) {// 如果不符合,返回错误信息return Result.fail("手机号格式错误!",400);}//获取验证码String code = stringRedisTemplate.opsForValue().get(LOGIN_CODE_KEY + loginForm.getPhone());String code_user = loginForm.getCode();//redis拿不到相关验证码,说明过期或者手机号不存在if (code==null){return Result.fail(USER_NOT_FOUND,USER_NOT_FOUNT_CODE);}//redis保存的验证码与输入的验证码不匹配if (!code.equals(code_user)){return Result.fail(CODE_NOT_MATCH,CODE_NOT_MATCH_OCDE);}User user = query().eq("phone", loginForm.getPhone()).one();log.info("user");log.info(user.toString());if (user==null){//返回用户不存在 这里预期进入注册网页return Result.fail(USER_NOT_FOUND,USER_NOT_FOUNT_CODE);}// 保存用户信息到 redis中// 随机生成token,作为登录令牌String token = UUID.randomUUID().toString(true);// 将User对象转为HashMap存储LoginForm loginForm1 = BeanUtil.copyProperties(user, LoginForm.class);log.info("loginForm1");log.info(loginForm1.toString());loginForm1.setCode("");//把null置为""空字符串类型Map<String, Object> userMap = BeanUtil.beanToMap(loginForm1, new HashMap<>(),CopyOptions.create().setIgnoreNullValue(true).setFieldValueEditor((fieldName, fieldValue) -> fieldValue.toString()));// 存储String tokenKey = LOGIN_USER_KEY + token;log.info(userMap.toString());stringRedisTemplate.opsForHash().putAll(tokenKey, userMap);//设置token有效期stringRedisTemplate.expire(tokenKey, LOGIN_USER_TTL, TimeUnit.MINUTES);//返回tokenreturn Result.ok(token);}
验证码的详细redis实现可以参考我之前的这边文章
redis实际开发应用简单实现-CSDN博客
接口
注册
http://localhost:8081/register/user
入参
{"userName":"t","phone":13689663339,"password":3
}
密码登录
http://localhost:8081/user/login
入参
{"phone":13610137901,"password":3
}
发送验证码
http://localhost:8081/user/code?phone=13610197901
路径参数phone
验证码登录
http://localhost:8081/user/login/code
入参
{"phone":13610137901,"password":3
}
已开源 可下载
可以帮点个star呗,感谢
GitHub - enjoykanyu/kanyu_server: 网站后端服务