Java 恢复密码的临时字段
当我恢复密码时,会在我的项目中生成一个密码,您可以使用该密码登录到您的帐户并更改密码,我不知道如何按时间限制临时密码字段?假设用户可以使用此密码登录一个小时,我有一个日期字段作为密码,但我不知道要与它进行比较Java 恢复密码的临时字段,java,spring,date,Java,Spring,Date,当我恢复密码时,会在我的项目中生成一个密码,您可以使用该密码登录到您的帐户并更改密码,我不知道如何按时间限制临时密码字段?假设用户可以使用此密码登录一个小时,我有一个日期字段作为密码,但我不知道要与它进行比较 public class SecurityUser implements UserDetails { private Integer id; private String username; private String password; private
public class SecurityUser implements UserDetails {
private Integer id;
private String username;
private String password;
private String email;
private Date lastPasswordReset;
private Collection<? extends GrantedAuthority> authorities;
private Boolean accountNonExpired = true;
private Boolean accountNonLocked = true;
private Boolean credentialsNonExpired = true;
private Boolean enabled = true;
private String temporaryPassword;
private Date validatyTime;
public类SecurityUser实现UserDetails{
私有整数id;
私有字符串用户名;
私有字符串密码;
私人字符串电子邮件;
私人日期lastPasswordReset;
private Collection您可以使用ScheduledTasks重置所有已过期的临时密码,并设置指示临时密码不再有效的标志
tl;dr
过期,不是有效期
跟踪密码过期的时刻。因此将validityTime
变量的名称更改为类似于whentemporationpasswordexpires
当用户尝试另一次登录时,您将捕获当前时刻,然后与存储的whenTemporaryPasswordExpires
进行比较
java.time
永远不要使用java.util.Date
。这是java最早版本中最糟糕的日期时间类之一。这些遗留类在几年前被采用JSR 310的java.time类完全取代
设定到期日
两个阶段中的第一个阶段是在生成临时密码时设置过期时间
捕捉当前时刻
Instant instant = Instant.now() ; // Capture the current moment in UTC.
确定临时密码有效期的业务策略。使用持续时间
以天(24小时的时间段,而不是日历天)、小时、分钟和秒为单位跟踪时间跨度
Duration d = Duration.ofHours( 1 ) ; // Policy says temporary password is good for one hour.
做一些日期-时间数学,将时间跨度(Duration
对象)添加到Instant
中,以获得表示未来时刻的新Instant
。请注意java.time是如何使用的,因此新的Instant
对象是基于原始值生成的
Instant expires = instant.plus( d ) ; // Date-time math, adding the one hour to the current moment gets us a moment 1 hour in the future.
将过期时间作为成员变量存储在类中
public class SecurityUser implements UserDetails {
private Integer id;
private String username;
…
private Instant whenTemporaryPasswordExpires;
…
}
将未来时刻指定给变量
user.whenTemporaryPasswordExpires = expires ;
将当前时刻与过期时间进行比较
第二阶段,当用户尝试登录时,我们查看当前时刻是否晚于过期时间。Instant
类具有比较方法,例如isBefore
和isAfter
boolean expired = Instant.now().isAfter( user.whenTemporaryPasswordExpires ) ;
if( expired ) {
// TODO: Display error message about temp pw expired. Offer new temp pw.
} else { // Else, not expired. Accept temporary password.
// TODO: Check submitted password to see if it matches temporary password issued earlier.
}
请注意,上面的所有代码都使用了。对于过期逻辑,不需要考虑时区。如果要显示过期,请搜索堆栈溢出以了解ZoneId
、ZonedDateTime
、以及DateTimeFormatter.ofLocalized…
在上面的讨论中,我忽略了一个明显的问题,即我们从不存储密码。我们使用satting和hash,但这是一个完全不同的讨论
关于java.time
该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,如,&
该项目现已启动,建议迁移到类
要了解更多信息,请参阅.和搜索堆栈溢出以获取许多示例和解释。规范为
您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要java.sql.*
classes
从哪里获得java.time类
- 、和更高版本-标准Java API的一部分,带有捆绑实现。
- Java9添加了一些次要功能和修复
- 及
- 大多数java.time功能都在中向后移植到Java6和Java7
-
- 更高版本的Android捆绑包实现了java.time类
- 对于早期的Android(您可以使用任务调度器来安排“临时密码删除程序”它将在1小时后执行。一个用户更喜欢正的布尔变量名:
Boolean accountExpired=false;
。并且更喜欢原始的Boolean
变量而不是Boolean
引用。最后,更喜欢现代的Instant
类而不是Date
类,因为它有设计问题,并且是long outleted.FYI,非常麻烦的旧日期时间类,如和java.text.SimpleDateFormat
,现在被内置在java 8和更高版本中的类所取代。请参阅。@Scheduled不允许在特定时间过后使用该函数,这并不是说,也许我错了。您可以在每秒钟调用一个调度程序ond,如果你愿意的话。在你的情况下,每隔几分钟就应该足够了。你能以某种方式获得登录时间,并将其与创建临时密码的时间进行比较吗?然后证明需要这样获得登录时间
boolean expired = Instant.now().isAfter( user.whenTemporaryPasswordExpires ) ;
if( expired ) {
// TODO: Display error message about temp pw expired. Offer new temp pw.
} else { // Else, not expired. Accept temporary password.
// TODO: Check submitted password to see if it matches temporary password issued earlier.
}