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.在注册页进行测试

在注册页填写信息:

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

原文地址:https://www.cnblogs.com/luckyplj/p/11626888.html