我正在尝试实现密码比较。首先,我尝试了这个:
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private OldPasswordsService oldPasswordsService;
Optional<OldPasswords> list = oldPasswordsService.findEncryptedPassword(passwordEncoder.encode("new password entered form web reset form"));
OldPasswords value = list.get();
boolean matches = passwordEncoder.matches("new password entered form web reset form", value.getEncryptedPassword());
if (matches)
{
return new ResponseEntity<>("PASSWORD_ALREADY_USED", HttpStatus.BAD_REQUEST);
}
else
{
OldPasswords oldPasswords = new OldPasswords();
oldPasswords.setEncryptedPassword(passwordEncoder.encode(resetDTO.getPassword()));
oldPasswords.setCreatedAt(LocalDateTime.now());
oldPasswordsService.save(oldPasswords);
}
旧密码表:
@Table(name = "old_passwords")
public class OldPasswords implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", unique = true, updatable = false, nullable = false)
private int id;
@Column(name = "encrypted_password", length = 255)
private String encryptedPassword;
我试图实现这一点:
......
return this.userService.findByLogin(resetDTO.getName()).map(user -> {
Optional<OldPasswords> list = oldPasswordsService.findEncryptedPassword(passwordEncoder.encode(resetDTO.getPassword()));
list.ifPresent(value -> {
boolean matches = passwordEncoder.matches(resetDTO.getPassword(), value.getEncryptedPassword());
if (matches) {
return new ResponseEntity<>("PASSWORD_ALREADY_USED", HttpStatus.BAD_REQUEST);
}
}).orElse(() -> {
OldPasswords oldPasswords = new OldPasswords();
oldPasswords.setEncryptedPassword(passwordEncoder.encode(resetDTO.getPassword()));
oldPasswordsService.save(oldPasswords);
});
return ok().build();
}).orElseGet(() -> notFound().build());
}
但是我得到这一行:
return new ResponseEntity<>("PASSWORD_ALREADY_USED", HttpStatus.BAD_REQUEST);
错误
Unexpected return value
您知道我该如何解决吗?
答案 0 :(得分:1)
是可能是List
!
因此:
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private OldPasswordsService oldPasswordsService;
...和
@Autowired
private UserXXXService userService;
...假设,您实际上是在尝试:
@RequestMapping(...)
public ResponseEntity<String> resetPassword(ResetPasswordDTO dto) {
...
...这就是我probalby要做的事情:
final Optional<User> user = this.userService.findByLogin(dto.getName()); // Optional or null?, let's assume Optional
// if user (login) exists:
if(user.isPresent()) {
// check old passwords, the method name/data structure lets assume it's rather List than Optional:
java.util.List<OldPasswords> list = oldPasswordsService.findEncryptedPassword(passwordEncoder.encode(dto.getPassword()));
if(list.isEmpty()) {// list is empty...
// do your things..
OldPasswords oP= new OldPasswords();
oP.setEncryptedPassword(passwordEncoder.encode(dto.getPassword()));
oldPasswordsService.save(oP);
return ResonseEntity.ok().build(); // ok!
} else {// otherwise:
return new ResponseEntity<>("PASSWORD_ALREADY_USED", HttpStatus.BAD_REQUEST);
}
} else { // otherwise (user.login not exists)
return ResponseEntity<>.notFound().build();
}
}
(未经测试或编译)
..一个技术问题/细节仍然/隐藏:我错过了“用户”和“ old_password”的“绑定” ...那么,它应该检查一个用户还是所有用户的旧密码?
第一个听起来更公平/正确:旧密码应该是“基于用户的”:
@Entity
// some unique constraints, when you have..., would be nice
public class OldPasswords implements Serializable { // singular is better for entity/table names!
....
@ManyToOne
@JoinColumn("user_id") // if you don't want to map the entity (for some reasons), you should still map the "id".
private User user;
// getter/setter ...
}
...
(影响最小),您可以:
public interface OldPasswordsRepository extends Repository<OldPasswords, Integer> { // <- Integer ???
List<OldPasswords> findByUserAndEncryptedPassword(User user, String pwd); // to use that...
}
编辑:要与最后三个密码@Peter匹配,您的数据结构需要(除user
之外)还需要一些“调整”,例如created
时间戳! )(比“版本/年龄列”更好的选择)
@Column(nullable = false) // final + instantiation is suited here
final Date created = new Date(); //long, LocalDateTime, DateTime... Timestamp, java.sql.Date... and many alternatives.
// getter
..那么您可以(在存储库中):
// untested!
List<OldPasswords> findTop3ByUserOrderByCreatedDesc(User user);
..并在控制器/服务中使用它,例如:
... // if user is present
List<OldPasswords> list = oldPasswordsRpository.findTop3ByUserOrderByCreatedDesc(user);
for(OldPasswords opw:list) {
// compare opw to dto.getPasword if match: return "bad request"
}
// after that (no bad request), store new (& old) password... (everywhere relevant),
// ...and when nothing fails:
return ResponseEntity.ok().build();
// else: user not present -> return not found