mirror of https://github.com/halo-dev/halo
Preserve remember-me option after authentication failure (#6844)
#### What type of PR is this? /kind bug /area core /milestone 2.20.x #### What this PR does / why we need it: This PR preserves `remember-me` option after authentication failure. #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/6835 #### Special notes for your reviewer: 1. Go to login page 2. Input invalid username or password and select `remember-me` option 3. Click `Login` button 4. See the result #### Does this PR introduce a user-facing change? ```release-note 修复登录失败后记住我选项被重置的问题 ```pull/6849/head
parent
b9da9d05ea
commit
b761fe2b79
|
@ -203,7 +203,7 @@ public class TokenBasedRememberMeServices implements ServerLogoutHandler, Rememb
|
|||
public Mono<Void> loginFail(ServerWebExchange exchange) {
|
||||
log.debug("Interactive login attempt was unsuccessful.");
|
||||
cancelCookie(exchange);
|
||||
return Mono.empty();
|
||||
return rememberMeRequestCache.saveRememberMe(exchange);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package run.halo.app.security.authentication.rememberme;
|
||||
|
||||
import static java.lang.Boolean.parseBoolean;
|
||||
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
import org.springframework.web.server.WebSession;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
@ -23,9 +21,7 @@ public class WebSessionRememberMeRequestCache implements RememberMeRequestCache
|
|||
@Override
|
||||
public Mono<Void> saveRememberMe(ServerWebExchange exchange) {
|
||||
return resolveFromQuery(exchange)
|
||||
.filter(Boolean::booleanValue)
|
||||
.switchIfEmpty(resolveFromForm(exchange))
|
||||
.filter(Boolean::booleanValue)
|
||||
.flatMap(rememberMe -> exchange.getSession().doOnNext(
|
||||
session -> session.getAttributes().put(SESSION_ATTRIBUTE_NAME, rememberMe))
|
||||
)
|
||||
|
@ -35,9 +31,7 @@ public class WebSessionRememberMeRequestCache implements RememberMeRequestCache
|
|||
@Override
|
||||
public Mono<Boolean> isRememberMe(ServerWebExchange exchange) {
|
||||
return resolveFromQuery(exchange)
|
||||
.filter(Boolean::booleanValue)
|
||||
.switchIfEmpty(resolveFromForm(exchange))
|
||||
.filter(Boolean::booleanValue)
|
||||
.switchIfEmpty(resolveFromSession(exchange))
|
||||
.defaultIfEmpty(false);
|
||||
}
|
||||
|
@ -50,22 +44,20 @@ public class WebSessionRememberMeRequestCache implements RememberMeRequestCache
|
|||
}
|
||||
|
||||
private Mono<Boolean> resolveFromQuery(ServerWebExchange exchange) {
|
||||
return Mono.just(
|
||||
parseBoolean(exchange.getRequest().getQueryParams().getFirst(DEFAULT_PARAMETER))
|
||||
);
|
||||
return Mono.justOrEmpty(exchange.getRequest().getQueryParams().getFirst(DEFAULT_PARAMETER))
|
||||
.map(Boolean::parseBoolean);
|
||||
}
|
||||
|
||||
private Mono<Boolean> resolveFromForm(ServerWebExchange exchange) {
|
||||
return exchange.getFormData()
|
||||
.map(form -> parseBoolean(form.getFirst(DEFAULT_PARAMETER)))
|
||||
.filter(Boolean::booleanValue);
|
||||
.mapNotNull(form -> form.getFirst(DEFAULT_PARAMETER))
|
||||
.map(Boolean::parseBoolean);
|
||||
}
|
||||
|
||||
private Mono<Boolean> resolveFromSession(ServerWebExchange exchange) {
|
||||
return exchange.getSession()
|
||||
.map(session -> {
|
||||
var rememberMeObject = session.getAttribute(SESSION_ATTRIBUTE_NAME);
|
||||
return rememberMeObject instanceof Boolean rememberMe ? rememberMe : false;
|
||||
});
|
||||
.mapNotNull(session -> session.getAttribute(SESSION_ATTRIBUTE_NAME))
|
||||
.filter(Boolean.class::isInstance)
|
||||
.cast(Boolean.class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,8 @@ import run.halo.app.plugin.PluginConst;
|
|||
import run.halo.app.security.AuthProviderService;
|
||||
import run.halo.app.security.HaloServerRequestCache;
|
||||
import run.halo.app.security.authentication.CryptoService;
|
||||
import run.halo.app.security.authentication.rememberme.RememberMeRequestCache;
|
||||
import run.halo.app.security.authentication.rememberme.WebSessionRememberMeRequestCache;
|
||||
|
||||
/**
|
||||
* Pre-auth login endpoints.
|
||||
|
@ -40,6 +42,9 @@ class PreAuthLoginEndpoint {
|
|||
|
||||
private final ServerRequestCache serverRequestCache = new HaloServerRequestCache();
|
||||
|
||||
private final RememberMeRequestCache rememberMeRequestCache =
|
||||
new WebSessionRememberMeRequestCache();
|
||||
|
||||
PreAuthLoginEndpoint(CryptoService cryptoService, GlobalInfoService globalInfoService,
|
||||
AuthProviderService authProviderService) {
|
||||
this.cryptoService = cryptoService;
|
||||
|
@ -91,7 +96,8 @@ class PreAuthLoginEndpoint {
|
|||
"authProvider", authProvider,
|
||||
"fragmentTemplateName", fragmentTemplateName,
|
||||
"socialAuthProviders", socialAuthProviders,
|
||||
"formAuthProviders", formAuthProviders
|
||||
"formAuthProviders", formAuthProviders,
|
||||
"rememberMe", rememberMeRequestCache.isRememberMe(exchange)
|
||||
// TODO Add more models here
|
||||
))
|
||||
));
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<div th:replace="~{__${fragmentTemplateName}__::form}"></div>
|
||||
|
||||
<div th:if="${authProvider.spec.rememberMeSupport}" class="form-item-compact">
|
||||
<input type="checkbox" id="remember-me" name="remember-me" value="true" />
|
||||
<input type="checkbox" id="remember-me" name="remember-me" value="true" th:checked="${rememberMe}"/>
|
||||
<label for="remember-me" th:text="#{form.rememberMe.label}"></label>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Reference in New Issue