Spring 引导数据 Rest JPA - 实体自定义创建(用户)
Spring Boot Data Rest JPA - Entity custom create (User)
我正在努力学习Spring。我使用以下工具创建了一个带有 Spring Boot 的项目:
- Spring 数据 JPA
- Spring 数据 REST
- Spring HATEOAS
- Spring 安全性
我正在尝试创建一个 User
实体。我希望用户有一个加密密码(+ salt)。
当我执行 POST
到 /api/users
时,我成功创建了一个新用户。
{
"firstname":"John",
"lastname":"Doe",
"email":"johndoe@example.com",
"password":"12345678"
}
但是我有两个问题:
- 密码以明文形式保存
- 盐为空
+----+---------------------+-----------+----------+----------+------+
| id | email | firstname | lastname | password | salt |
+----+---------------------+-----------+----------+----------+------+
| 1 | johndoe@example.com | John | Doe | 12345678 | NULL |
+----+---------------------+-----------+----------+----------+------+
我认为问题是使用了默认构造函数,而不是我创建的另一个构造函数。我是 Spring 和 JPA 的新手,所以我一定遗漏了一些东西。这是我的代码。
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);
}
}
另外,如果有人发现我做错了,我想指出我where/how我应该把用户登录码(解密)。
谢谢。
如果你想Spring使用你的构造函数,你需要
- 删除无参数构造函数
- 用
@JsonProperty
像这样 注释另一个构造函数中的每个参数
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);
}
您不需要向 BCryptPasswordEncoder
提供加盐值,因为它本身已经加盐了密码。
所以,这就是我解决问题的方法:我创建了一个控制器作为我的自定义端点,然后我创建了一个服务,在其中放置了我想要创建用户的逻辑。这是代码:
UserController.java
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/api/register")
@ResponseBody
public Long register(@RequestBody User user) {
return userService.registerUser(user);
}
...
}
用户服务.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();
}
...
}
所以通过 POST
和
{
"firstname":"John",
"lastname":"Doe",
"email":"johndoe@example.com",
"password":"12345678"
}
在 /api/register
中,我现在可以使用散列密码创建用户。
我正在努力学习Spring。我使用以下工具创建了一个带有 Spring Boot 的项目:
- Spring 数据 JPA
- Spring 数据 REST
- Spring HATEOAS
- Spring 安全性
我正在尝试创建一个 User
实体。我希望用户有一个加密密码(+ salt)。
当我执行 POST
到 /api/users
时,我成功创建了一个新用户。
{
"firstname":"John",
"lastname":"Doe",
"email":"johndoe@example.com",
"password":"12345678"
}
但是我有两个问题:
- 密码以明文形式保存
- 盐为空
+----+---------------------+-----------+----------+----------+------+ | id | email | firstname | lastname | password | salt | +----+---------------------+-----------+----------+----------+------+ | 1 | johndoe@example.com | John | Doe | 12345678 | NULL | +----+---------------------+-----------+----------+----------+------+
我认为问题是使用了默认构造函数,而不是我创建的另一个构造函数。我是 Spring 和 JPA 的新手,所以我一定遗漏了一些东西。这是我的代码。
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);
}
}
另外,如果有人发现我做错了,我想指出我where/how我应该把用户登录码(解密)。
谢谢。
如果你想Spring使用你的构造函数,你需要
- 删除无参数构造函数
- 用
@JsonProperty
像这样 注释另一个构造函数中的每个参数
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);
}
您不需要向 BCryptPasswordEncoder
提供加盐值,因为它本身已经加盐了密码。
所以,这就是我解决问题的方法:我创建了一个控制器作为我的自定义端点,然后我创建了一个服务,在其中放置了我想要创建用户的逻辑。这是代码:
UserController.java
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/api/register")
@ResponseBody
public Long register(@RequestBody User user) {
return userService.registerUser(user);
}
...
}
用户服务.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();
}
...
}
所以通过 POST
和
{
"firstname":"John",
"lastname":"Doe",
"email":"johndoe@example.com",
"password":"12345678"
}
在 /api/register
中,我现在可以使用散列密码创建用户。