zoukankan      html  css  js  c++  java
  • 044 用户注册功能04--完成注册功能

    实现用户注册功能,需要对用户密码进行加密存储,使用MD5加密,加密过程中使用随机码作为salt加盐。另外还需要对用户输入的短信验证码进行校验。

    1.接口说明

    (1)接口路径:

    POST /register

    (2)返回结果:

    无返回值。

    状态码:

    • 201:注册成功

    • 400:参数有误,注册失败

    • 500:服务器内部异常,注册失败

    (3)基本逻辑:

    • 1)校验短信验证码

    • 2)生成盐

    • 3)对密码加密

    • 4)写入数据库

    • 5)删除Redis中的验证码

    2.UserController

    /**
         * 注册
         * @param user  接收用户对象信息(form表单提交,user对象进行接收)
         * @param code 接收表单参数--手机验证码
         * @return
         */
        @PostMapping("register")
        public ResponseEntity<Void> register(User user, @RequestParam("code") String code) {
            Boolean boo = this.userService.register(user, code);
            if (boo == null || !boo) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
            }
            return new ResponseEntity<>(HttpStatus.CREATED);
        }

    3.UserService

    /**
         * 用户注册功能
         * @param user
         * @param code
         * @return
         */
        public Boolean register(User user, String code) {
            // 校验短信验证码
            String cacheCode = this.redisTemplate.opsForValue().get(KEY_PREFIX + user.getPhone());
            if (!StringUtils.equals(code, cacheCode)) {
                return false;
            }
    
            // 生成盐
            String salt = CodecUtils.generateSalt();
            user.setSalt(salt);
    
            // 对密码加密
            user.setPassword(CodecUtils.md5Hex(user.getPassword(), salt));
    
            // 强制设置不能指定的参数为null
            user.setId(null);
            user.setCreated(new Date());
            // 添加到数据库
            boolean b = this.userMapper.insertSelective(user) == 1;
    
            if(b){
                // 注册成功,删除redis中的记录
                this.redisTemplate.delete(KEY_PREFIX + user.getPhone());
            }
            return b;
        }

    此处使用了CodeUtils:

    该工具类需要apache加密工具包:

    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
    </dependency>

    4.测试

    我们通过PostMan测试:

    http://api.leyou.com/api/user/register?username=lucky&password=plj824&phone=17826828544&code=984971

    查看数据库:

    5.hibernate-validate

    刚才虽然实现了注册,但是服务端并没有进行数据校验,而前端的校验是很容易被有心人绕过的。所以我们必须在后台添加数据校验功能:

    我们这里会使用Hibernate-Validator框架完成数据校验:

    而SpringBoot的web启动器中已经集成了相关依赖:

     (1)Hibernate Validator简介

    Hibernate Validator是Hibernate提供的一个开源框架,使用注解方式非常方便的实现服务端的数据校验

    官网:http://hibernate.org/validator/

    Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint(约束) 的实现,除此之外还有一些附加的 constraint。

    在日常开发中,Hibernate Validator经常用来验证bean的字段,基于注解,方便快捷高效。

    (2)Bean校验的注解

     

    (3)给User添加校验

    我们在leyou-user-interface中添加Hibernate-Validator依赖:

    <dependency>
        <groupId>org.hibernate.validator</groupId>
        <artifactId>hibernate-validator</artifactId>
    </dependency>

    我们在User对象的部分属性上添加注解:

    package lucky.leyou.user.domain;
    
    import com.fasterxml.jackson.annotation.JsonIgnore;
    import org.hibernate.validator.constraints.Length;
    
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.Table;
    import javax.validation.constraints.Pattern;
    import java.util.Date;
    
    @Table(name = "tb_user")
    public class User {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private Long id;
    
        @Length(min = 4, max = 30, message = "用户名只能在4~30位之间")
        private String username;// 用户名
    
        @JsonIgnore
        @Length(min = 4, max = 30, message = "密码只能在4~30位之间")
        private String password;// 密码
    
        @Pattern(regexp = "^1[35678]\d{9}$", message = "手机号格式不正确")
        private String phone;// 电话
    
        private Date created;// 创建时间
    
        @JsonIgnore //对象序列化为json字符串时,忽略该属性
        private String salt;// 密码的盐值
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getPhone() {
            return phone;
        }
    
        public void setPhone(String phone) {
            this.phone = phone;
        }
    
        public Date getCreated() {
            return created;
        }
    
        public void setCreated(Date created) {
            this.created = created;
        }
    
        public String getSalt() {
            return salt;
        }
    
        public void setSalt(String salt) {
            this.salt = salt;
        }
    }

    (5)在controller上进行控制

    在controller中改造register方法,只需要给User添加 @Valid注解即可。

    (6)测试

    重启微服务LeyouUserApplication

    http://api.leyou.com/api/user/register?username=lucky&password=plj&phone=17826828544&code=984971

    我们故意填错:

     

    6.根据用户名和密码查询用户

    功能说明

    查询功能,根据参数中的用户名和密码查询指定用户

    接口路径

     

    GET /query

    参数说明

    返回结果

    用户的json格式数据

    {
        "id": 6572312,
        "username":"test",
        "phone":"13688886666",
        "created": 1342432424
    }

    状态码

    • 200:注册成功

    • 400:用户名或密码错误

    • 500:服务器内部异常,注册失败

    (1)controller

    /**
     * 根据用户名和密码查询用户
     * @param username
     * @param password
     * @return
     */
    @GetMapping("query")
    public ResponseEntity<User> queryUser(
        @RequestParam("username") String username,
        @RequestParam("password") String password
        ) {
            User user = this.userService.queryUser(username, password);
            if (user == null) {
                return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
            }
            return ResponseEntity.ok(user);
        }

    (2)service

    /**
         * 根据用户名和密码进行登录
         * @param username 用户名
         * @param password 密码
         * @return
         */
        public User queryUser(String username, String password) {
            // 查询
            User record = new User();
            record.setUsername(username);
            User user = this.userMapper.selectOne(record);
            // 校验用户名
            if (user == null) {
                return null;
            }
            // 校验密码
            if (!user.getPassword().equals(CodecUtils.md5Hex(password, user.getSalt()))) {
                return null;
            }
            // 用户名密码都正确
            return user;
        }

    要注意,查询时也要对密码进行加密后判断是否一致。

    (3)测试

    http://api.leyou.com/api/user/query?username=lucky&password=plj824

    7.在注册页进行测试

    在注册页填写信息:

    提交发现页面自动跳转到了登录页,查看数据库:

  • 相关阅读:
    Python生成验证码
    Django设置
    OpenStack安装后检查流程总结
    利用src.rpm包修改源码后重新制作rpm包
    Python知识点:distutils常用子模块
    libvirt, libvirt-python, libvirtd 关系浅析
    Python知识点: os.popen
    Python知识点: __import__
    修改initrd.img里ko文件的一个小tips
    关于openstack自动化安装的一点思考
  • 原文地址:https://www.cnblogs.com/luckyplj/p/11626888.html
Copyright © 2011-2022 走看看