意外的 return 值
Unexpected return value
我正在尝试实施密码比较。首先我尝试了这个:
@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 旧密码:
@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
你知道我该如何解决这个问题吗?
它是可能List
!
因此:
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private OldPasswordsService oldPasswordsService;
...和
@Autowired
private UserXXXService userService;
...让我们假设,您实际上正在尝试:
@RequestMapping(...)
public ResponseEntity<String> resetPassword(ResetPasswordDTO dto) {
...
...这就是我可能会采用的方式:
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();
}
}
(未测试也未编译)
..一个技术 question/detail remains/hidden:我想念 "user" 和 "old_password" 的 "binding"... 所以,它应该检查旧的一个用户或所有用户的密码?
第一个听起来更多fair/correct:旧密码应该是"user based":
@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
)一些"tweak" - 比如created
时间戳!;)(比 "version/age column")
更好的选择
@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);
..并在 controller/service 中使用它,例如:
... // 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
我正在尝试实施密码比较。首先我尝试了这个:
@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 旧密码:
@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
你知道我该如何解决这个问题吗?
它是可能List
!
因此:
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private OldPasswordsService oldPasswordsService;
...和
@Autowired
private UserXXXService userService;
...让我们假设,您实际上正在尝试:
@RequestMapping(...)
public ResponseEntity<String> resetPassword(ResetPasswordDTO dto) {
...
...这就是我可能会采用的方式:
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();
}
}
(未测试也未编译)
..一个技术 question/detail remains/hidden:我想念 "user" 和 "old_password" 的 "binding"... 所以,它应该检查旧的一个用户或所有用户的密码?
第一个听起来更多fair/correct:旧密码应该是"user based":
@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
)一些"tweak" - 比如created
时间戳!;)(比 "version/age column")
@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);
..并在 controller/service 中使用它,例如:
... // 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