首页 > 解决方案 > 在 Spring Boot 中有效地匹配密码 - JPA

问题描述

我有这样的User课:

@Data
@Entity
public class User {
@Id @GeneratedValue Long userID;
String eMail;
String passwordHash;
}

我有这样的数据:

[{"userID":1,"passwordHash":"asdasd","email":"admin@admin.com"},
{"userID":2,"passwordHash":"12345","email":"admin1asdasd@admin.com"}]

我有两种方法,一种是获取单个用户:

// Single item

@GetMapping("/user/{id}")
User one(@PathVariable Long id) {

    return repository.findById(id)
            .orElseThrow(() -> new UserNotFoundException(id));
}

检索所有用户的其他方法:

// Aggregate root

@GetMapping("/user")
List<User> all() {
    return repository.findAll();
}

现在我该如何匹配密码?什么是有效的方法?

标签: jsonspring-bootjpapasswords

解决方案


您可能需要考虑这种方法:通常,您应该将散列密码保存在数据库中,并使用散列值检查密码。Bcrypt 是散列的一个很好的选择,它可以很容易地与 Spring 集成。

如上面链接中所述,您可以定义密码编码器服务:

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

你可以像这样使用它:

@Autowired
private PasswordEncoder passwordEncoder;

//...
User user = new User();
user.setFirstName(accountDto.getFirstName());
user.setLastName(accountDto.getLastName());

user.setPassword(passwordEncoder.encode(accountDto.getPassword()));

user.setEmail(accountDto.getEmail());
user.setRole(new Role(Integer.valueOf(1), user));
repository.save(user);

其中accountDto包含明文密码。

现在您可以公开一个专门的登录方法来比较散列值,类似于以下内容:

void login(String username, char[] password) throws Exception {
    User user = userRepository.findByUsername(username);
    if (user != null) {
        String encodedPassword = user.getPassword();
        if(passwordEncoder.matches(String.valueOf(password), encodedPassword)) {
            return;
        }
    }
    throw new Exception("User cannot be authenticated");
}

推荐阅读