Spring Boot JPA Boot Data - Custom Entity Creation (User)

I am trying to learn Spring. I created the project using Spring Boot using the following tools:

  • Spring JPA Data
  • Spring data rest
  • Spring hateas
  • Spring Security

I am trying to create a User object. I want the user to have an encrypted password (+ salt).

When I do POST before /api/users , I successfully create a new user.

 { "firstname":"John", "lastname":"Doe", "email":" johndoe@example.com ", "password":"12345678" } 

But I have 2 problems:

  • password is stored in text
  • salt is zero
 +----+---------------------+-----------+----------+----------+------+ | id | email | firstname | lastname | password | salt | +----+---------------------+-----------+----------+----------+------+ | 1 | johndoe@example.com | John | Doe | 12345678 | NULL | +----+---------------------+-----------+----------+----------+------+ 

The problem is that the default constructor is used, and not the other that I created. I am new to Spring and JPA, so I have to skip something. Here is my code.

User.java

 @Entity @Table(name = "users") public class User{ @Id @GeneratedValue private Long id; @Column(nullable = false) public String firstname; @Column(nullable = false) public String lastname; @Column(nullable = false, unique = true) public String email; @JsonIgnore @Column(nullable = false) public String password; @JsonIgnore @Column private String salt; public User() {} public User(String email, String firstname, String lastname, String password) { this.email = email; this.firstname = firstname; this.lastname = lastname; this.salt = UUID.randomUUID().toString(); this.password = new BCryptPasswordEncoder().encode(password + this.salt); } @JsonIgnore public String getSalt() { return salt; } @JsonProperty public void setSalt(String salt) { this.salt = salt; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getFirstname() { return firstname; } public void setFirstname(String firstname) { this.firstname = firstname; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getLastname() { return lastname; } public void setLastname(String lastname) { this.lastname = lastname; } @JsonIgnore public String getPassword() { return password; } @JsonProperty public void setPassword(String password) { this.password = password; } } 

UserRepository.java

 public interface UserRepository extends JpaRepository<User, Long> { public User findByEmail(String email); public User findByEmailAndPassword(String email, String password); } 

Application.java

 @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application .class, args); } } 

Also, if someone finds out what I did wrong, I would like to tell me where / how I should put the user login code (decryption).

Thanks.

+5
source share
2 answers

So, here is how I solved my problem: I created the controller as my endpoint, and then created the service in which I placed the logic that I wanted to create for the user. Here is the code:

UserController.java

 @Controller public class UserController { @Autowired private UserService userService; @RequestMapping("/api/register") @ResponseBody public Long register(@RequestBody User user) { return userService.registerUser(user); } ... } 

UserService.java

 @Service public class UserService { @Autowired private UserRepository userRepository; public Long registerUser(User user) { user.setPassword(new BCryptPasswordEncoder().encode(password)); userRepository.save(user); return user.getId(); } ... } 

so making a POST with

 { "firstname":"John", "lastname":"Doe", "email":" johndoe@example.com ", "password":"12345678" } 

in /api/register , now I can create a user with a hashed password.

+3
source

If you want Spring to use your constructor, you need

  • remove constructor without arguments
  • annotate each parameter in another constructor with @JsonProperty as follows
 public User(@JsonProperty("email") String email, @JsonProperty("firstname") String firstname, @JsonProperty("lastname") String lastname, @JsonProperty("password") String password) { this.email = email; this.firstname = firstname; this.lastname = lastname; this.password = new BCryptPasswordEncoder().encode(password); } 

You do not need to specify a salt value for BCryptPasswordEncoder , because it already has salt passwords in itself.

+2
source

All Articles