json - 在 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();
}
现在我该如何匹配密码?什么是有效的方法?
解决方案
您可能需要考虑这种方法:通常,您应该将散列密码保存在数据库中,并使用散列值检查密码。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");
}
推荐阅读
- database - 如何将引用数据从 CSV 文件导入 SQLite?
- python - 连接/关闭数据库一次 VS 每次更改时都这样做 - 哪个更好?
- javascript - 如何解决自动完成错误“NoReverseMatch at /”?我正在制作 django 项目有人可以帮助我吗
- python - 列出带有列表的嵌套字典
- google-api - 尽管没有用尽配额限制,但仍超出了“每日查询次数”限制
- c# - unity c# -> 将骨骼旋转到目标 Vector3
- java - @Autowired(required=false) bean 在从另一个模块调用时为空
- javascript - 邮递员可以进行护照身份验证,但不能使用 fetch()
- google-apps-script - Google 表格脚本:无法添加或删除项目属性
- go - 通过“go get github.com/gin-gonic/gin”安装 Gin 的问题