恢复密码的临时字段

时间:2019-01-15 10:35:06

标签: java spring date

恢复密码时,我的项目中会生成一个密码,您可以使用该密码登录帐户并更改密码,我不明白如何按时间限制临时密码字段?假设用户可以使用此密码登录一个小时,我有一个密码的日期字段,但是我不知道该与什么进行比较

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;

2 个答案:

答案 0 :(得分:3)

tl; dr

Instant                                // Represents a moment in UTC.
.now()                                 // Capture the current moment, as seen through the wall-clock time of UTC.
.ifAfter(                              // Compare one `Instant` object to another.
    user.whenTemporaryPasswordExpires  // This stored moment (an `Instant`) represents an hour later than the current moment captured when the temporary password was issued. 
)                                      // Returns a boolean.

到期,不是有效期

跟踪密码过期的时间。因此,将validityTime变量的名称更改为whenTemporaryPasswordExpires

当用户尝试再次登录时,您将捕获当前时刻,然后将其与存储的whenTemporaryPasswordExpires进行比较。

java.time

请勿使用java.util.Date。这是Java最早版本中可怕的日期时间类之一。这些遗留类完全由 java.time 类在采用JSR 310之前取代。

设置到期时间

两个阶段的第一阶段,设置生成临时密码时的到期时间。

捕获当前时刻。

Instant instant = Instant.now() ;  // Capture the current moment in UTC.

确定临时密码可以使用多长时间的业务策略。使用Duration可以按照天(24小时的时间,不是日历天),小时,分钟和秒来跟踪时间跨度。

Duration d = Duration.ofHours( 1 ) ;  // Policy says temporary password is good for one hour.

做一些日期时间数学运算,将时间跨度(Duration对象)添加到Instant以获得代表未来时刻的新Instant。请注意 java.time 如何使用immutable objects,因此将产生一个新的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类具有比较方法,例如isBeforeisAfter

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.
}

请注意,以上所有代码均使用UTC。到期逻辑无需费时。如果要显示到期时间,请搜索堆栈溢出以了解ZoneIdZonedDateTimeDateTimeFormatter.ofLocalized…


在上面的讨论中,我忽略了一个显而易见的问题,即我们从不存储密码。我们使用盐化和散列,但这是完全不同的讨论。


关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

答案 1 :(得分:0)

您可以使用ScheduledTasks重置所有已过期的临时密码,并设置一个标志,指示临时密码不再有效。

https://spring.io/guides/gs/scheduling-tasks/