简单实现用户注册验证功能的步骤及代码

用户注册验证

操作步骤:(拆分需求)
1>效验参数不能为空
2>两次输入的密码是否一样
3>效验手机号码是否正确
4>效验手机号码是否唯一
5>效验短信验证码是否正确
6>注册

注意点:核心属性 必须自己控制
1>验证手机号码是否已经被注册过

controller

  @GetMapping("/checkPhone")
    public Object checkPhone(String phone){
        return userInfoService.checkPhone(phone);
    }

service (页面需要的是一个boolean值)

	/**
     * 通过phone 查询用户
     * @param phone
     * @return
     */
    Boolean checkPhone(String phone);

@Override
    public Boolean checkPhone(String phone) {
        UserInfo userInfo = repository.findByPhone(phone);
        return userInfo != null; //为空表示不存在
    }
2>生成一个随机且唯一的验证码,发送给用户
#### 短信验证码发送操作逻辑:
​	1>点击按钮发送短信到注册那个手机号码上
​	2>注册手机收到短信验证码,并输入
​	3>低级注册携带短信验证码,判断验证码是否正确
​	4>将code缓存到redis对象,并设置过期时间

controller类

@GetMapping("/sendVerifyCode")
    public Object sendVerifyCode(String phone){
        userInfoService.sendVerifyCode(phone);
        return JsonResult.success();
    }

service业务层

 /**
     * 发送短信验证码
     * @param phone
     */
    void sendVerifyCode(String phone);


    /**
     * 发送验证码
     * @param phone
     */
    @Override
    public void sendVerifyCode(String phone) {
        //创建4位数的验证码(随机,唯一)
        String code = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 4);

        //拼接短信验证码提示信息
        StringBuilder sb = new StringBuilder(50);
        sb.append("您注册的验证码是:").append(code).append(",请在").append(Consts.VERIFY_CODE_VAI_TIME).append("分钟内提交");

        //假装发短信
        System.out.println(sb);
        //真是发送短信本质就是使用java发起http请求即可
        //RestTemplate用于发起http请求的工具类
       /* RestTemplate template = new RestTemplate();
        String url = "https://way.jd.com/chuangxin/dxjk?mobile={1}&content=【创信】{2}&appkey={3}";

        String rep = template.getForObject(url, String.class, phone, sb.toString(), "81160ff2102302361058123544194785");

        System.out.println(rep);*/

        //缓存验证码
        userInfoRedisService.setVerifyCode(phone, code);

    }

AssertUtil工具类

public class AssertUtil {

    public static void hasLength(String value,String msg){
        //判断传入的数值是否为空
        if(!StringUtils.hasLength(value)){
            throw new LogicException(msg);
        }
    }
	//判断两个值是否一致
    public static void isEquales(String v1, String v2,String msg) {
        if(v1 == null || v2 == null){
            throw new LogicException(msg);
        }
        if(!v1.equals(v2)){
            throw new LogicException(msg);
        }
    }
}
3>校验注册信息是否正确
操作步骤:(拆分需求)
​	1>效验手机号码是否正确
​	2>效验手机是否已经被注册
​	3>效验注册信息格式是否正确(非空效验,等值效验,长度效验...)
​	4>发送注册短信 验证码
​	5>用户注册

controller (根据前端带过来的数据定义 方法,参数,返回类型)

@PostMapping("/regist")
    public Object regist(String phone,String nickname,String password,String rpassword,String verifyCode){
        userInfoService.regist(phone,nickname,password,rpassword,verifyCode);
        return JsonResult.success();
    }

service业务层

/**
     * 用户注册信息
     * @param phone
     * @param nickname
     * @param password
     * @param rpassword
     * @param verifyCode
     */
    void regist(String phone, String nickname, String password, String rpassword, String verifyCode);

@Override
    public void regist(String phone, String nickname, String password, String rpassword, String verifyCode) {
        //判断验证信息是否为空
        AssertUtil.hasLength(phone, "手机号码不能为空");
        AssertUtil.hasLength(nickname, "昵称不能为空");
        AssertUtil.hasLength(password, "密码不能为空");
        AssertUtil.hasLength(rpassword, "确认密码不能为空");
        AssertUtil.hasLength(verifyCode, "验证码不能为空");

        //验证两次输入的密码是否一样
        AssertUtil.isEquales(password,rpassword);
        //验证手机号码是否存在
        if(this.checkPhone(phone)){
            throw new LogicException("手机号码已经存在");
        }
        //校验短信验证码是否正确
        String code = userInfoRedisService.getVerifyCode(phone);
        if(!verifyCode.equalsIgnoreCase(code)){
            throw new LogicException("验证码输入有误");
        }

        UserInfo userInfo = new UserInfo();
	//把用户数据设置到对象中
        userInfo.setNickname("靓仔");
        userInfo.setPhone(phone);
        userInfo.setEmail("123@qq.com");
        userInfo.setPassword(password);
        userInfo.setGender(1);//1表示男
        userInfo.setLevel(0);//用户级别
        userInfo.setCity("广州");
        userInfo.setHeadImgUrl("/images/default.jpg");//头像路径
        userInfo.setInfo("");//个性签名
        userInfo.setState(0);//状态
	//保存用户对象
        repository.save(userInfo);

    }

自定义逻辑异常

/**
 * 自定义的异常
 * 1:用于区分系统异常与主动抛出的异常
 */
public class LogicException extends RuntimeException{

    public LogicException(String msg){
        super(msg);
    }
}

统一异常处理

@ControllerAdvice
public class CommonExceptionHandler {

    @ExceptionHandler(LogicException.class)
    @ResponseBody
    public Object logicExp(Exception e, HttpServletResponse resp){
        //打印捕获到的异常信息
        e.getStackTrace();
        //设置编码格式
        resp.setContentType("application/json;charset=utf-8");

        return JsonResult.error(JsonResult.CODE_ERROR_PARAM, e.getMessage(), null);
    }

    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    public Object runtimeExp(Exception e, HttpServletResponse resp){
        //打印捕获到的异常信息
        e.getStackTrace();
        //设置编码格式
        resp.setContentType("application/json;charset=utf-8");

        return JsonResult.defaultError();
    }
}
4>验证通过跳转到登录界面

使用令牌方式登录流程:

1>通过请求获取username跟password,查看数据库得到用户对象user

2>通过user对象判断user是否为nll,如果是null提示信息,如果不为null表示登录成功

3>通过UUID方式创建token令牌(要求唯一,随机)
	String token = UUID.randomUUID()..
4>以token为key,用户对象为user作为value缓存到redis数据库中,token的有效时间设置为30分钟

5>将token跟user对象使用接送格式返回浏览器

6>浏览器接收并解析响应数据得到token跟user对象,缓存到cookie{此时的cookie也设置有小时间是30分钟]

7>第二次访问接口时,前端发请求时,将浏览器中缓存的token数据添加到请求头中,跟请求参数一起携带到服务器

8>服务器端通过请求对象,调用getHeander("token")得到前端传过来的token数据

9>判断user对象是否为null,决定当前是否已经登录
	1>如果user为null,表示没有登录
	2>如果user不是null,表示已经登录
	此时需要重置token的有效时间[30分钟]

controller类

    @PostMapping("/login")
    public Object login(String username,String password){
        //通过用户传进来的 username, password 查询数据库中的用户信息
        UserInfo user = userInfoService.login(username, password);
		//给用户设置对应的令牌(随机,唯一)作为标识
        String token = userInfoRedisService.setToken(user);
        //把token,user存到reids中
        HashMap<String, Object> map = new HashMap<>();
        map.put("user", user);
        map.put("token", token);
        return JsonResult.success(map);
    }

service业务层

/**
     * 用户登录信息
     * @param username
     * @param password
     * @return
     */
    UserInfo login(String username, String password);


 @Override
    public UserInfo login(String username, String password) {
        //UserInfo user = repository.findByUsernameAndPassword(username,password);
        //通过用户名查询数据库中是否存在该对象
        UserInfo user = repository.findByPhone(username);

        //账号不存在或密码不正确,抛出异常
        if(user == null || !user.getPassword().equals(password)){
            throw new LogicException("账号或密码错误");
        }
        //为了账号安全,再返回之前把密码设置为空(在前端看控制台,不显示密码)
        user.setPassword("");
        return user;
    }

此文及供参考,有需要的请根据自己的前端页面所需要(传入参数,返回值类型,方法映射路径修改)数据进行修改.
最后感谢您的查看,希望此文章能帮到您!

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值