loginForm 登录表单
loginForm 组件用于输入凭据和认证信息。
XML 元素 |
|
|---|---|
Java 类 |
|
基本用法
基本的 loginForm 包含用户名和密码字段以及一个登录按钮。还可以显示地区语言选择器、记住我 复选框以及 忘记密码 按钮。
标签和消息
使用内部的 form 元素设置表单标题、字段标签和按钮文本。其值可以是文字文本或 消息包 键值。示例中还定义了用于身份验证失败的 errorMessage 内容以及表单下方的 additionalInformation 内容:
<loginForm>
<form title="Welcome"
username="Username or email"
password="Password"
rememberMe="Remember me"
submit="Log in"
forgotPassword="Forgot password"/>
<errorMessage title="Login failed"
message="Check that you have entered the correct username and password and try again"/>
<additionalInformation message="Additional information"/>
</loginForm>
可选元素
可以通过可见性属性配置是否显示语言选择框、记住我 复选框或 忘记密码 按钮,无需修改表单内部结构:
<loginForm localesVisible="true"
rememberMeVisible="true"
forgotPasswordButtonVisible="true">
//...
</loginForm>
记住我
Remember me 选项保存一个持久化的浏览器 token,因此即使 HTTP 会话过期或应用程序重启,这个保存的认证会话依然有效。如果有其他 UI 逻辑需要对这个选项的更改做出响应,可以在认证时从 LoginEvent 中读取选择状态并使用 RememberMeChangedEvent 事件。
请参考 Spring Security Remember-Me 文档 了解底层的认证逻辑。
认证
标准登录视图订阅 LoginEvent,使用所选的语言环境,并将输入的凭据和“记住我”的状态传递给 AuthenticationManager。通过表单的错误状态提示身份验证失败:
@ViewComponent
private JmixLoginForm login; (1)
@Subscribe("login")
public void onLogin(final LoginEvent event) {
try {
loginViewSupport.authenticate(
AuthDetails.of(event.getUsername(), event.getPassword())
.withLocale(login.getSelectedLocale()) (2)
.withRememberMe(login.isRememberMe()) (3)
);
} catch (final BadCredentialsException | DisabledException | LockedException | AccessDeniedException e) {
log.info("Login failed", e);
event.getSource().setError(true);
}
}
| 1 | 注入表单,以便在控制器中更新其状态。 |
| 2 | 为应用程序设置所选的语言。 |
| 3 | 将复选框的值传递至认证 token。 |
认证错误处理
当需要为用户提供更具体的认证失败信息时,可以扩展登录处理器。下面的示例中,检测账户锁定异常,显示针对该异常的信息并记录失败次数:
@Subscribe("login")
public void onLogin(final AbstractLogin.LoginEvent event) {
try {
loginViewSupport.authenticate(
AuthDetails.of(event.getUsername(), event.getPassword())
.withLocale(login.getSelectedLocale())
.withRememberMe(login.isRememberMe())
);
}
catch (final BadCredentialsException | DisabledException | LockedException | AccessDeniedException e) {
if (e instanceof LockedException) {
JmixLoginI18n loginI18n = createLoginI18n();
loginI18n.getErrorMessage().setMessage(e.getMessage()); (1)
login.setI18n(loginI18n);
} else {
login.setI18n(createLoginI18n());
}
log.warn("Login failed for user '{}': {}", event.getUsername(), e.toString()); (2)
event.getSource().setError(true);
}
}
| 1 | 为 LockedException 查找错误消息。 |
| 2 | 记录失败尝试。 |
登录视图的样式
该示例将表单描述符与组件级别的 CSS 结合。XML 提供登录组件,CSS 控制周围的布局、背景图片和表单定位:
<div classNames="custom-login">
<loginForm id="login"
rememberMeVisible="false"
forgotPasswordButtonVisible="false"
localesVisible="false">
<form title="Custom Login Sample"
username="Username"
password="Password"
rememberMe="Remember me"
submit="Log in"
forgotPassword="Forgot password"/>
</loginForm>
</div>
.custom-login {
width: 100%;
background-image: url("background.png");
background-position: center;
background-size: cover;
display: flex;
height: 25em;
}
.custom-login jmix-login-form {
align-items: center;
display: flex;
max-width: 25em;
background-color: var(--lumo-base-color);
}
.custom-login vaadin-login-form-wrapper {
background-image: none;
}
事件和处理器
下面是 loginForm 的特殊事件和处理器:
| 名称 | 描述 |
|---|---|
当用户点击 Forgot password 时触发。 |
|
当用户选择不同语言时触发。 |
|
当用户提交填写完成的凭据时触发。 |
|
当 Remember me 复选框的状态变化时触发。 |
|
为语言选择器中的每个语言提供显示的文本。 |
下面是 loginForm 支持的其他通用事件:
XML 内部元素
一个 loginForm 可以包含 form、errorMessage 和 additionalInformation 作为其内部元素。form 元素定义标签和按钮文本,errorMessage 定义认证失败消息,additionalInformation 在表单下方添加辅助内容。