我已经使用JSF 2.2和PrimeFaces 5.3构建了登录功能屏幕。但是,我有一个问题。假设用户输入了用户名和密码,但其中一个不正确。发生这种情况时,我向用户显示一条错误消息:“用户名和/或密码不正确”。问题是,那时我正在存储会话。我只想在用户成功登录后存储会话。我的登录表单如下所示:
<f:metadata>
<f:viewParam name="tipo" value="#{loginTipoController.tipo.tipo}" />
</f:metadata>
<h:form id="login">
<p:focus context="login" />
<p:graphicImage url="img/logog.JPG" width="448" height="119" />
<p>Digite su usuario y password.</p>
<p:outputLabel for="usuario" value="Usuario:" />
<p:inputText id="usuario" value="#{loginController.login.username}" />
<p:outputLabel for="password" value="Password:" />
<p:password id="password" value="#{loginController.login.password}" />
<p:messages autoUpdate="true" for="usuarioPassword" />
<p:commandButton value="Login" action="#{loginController.login()}" />
<p:button value="Regresar" outcome="index.jsf" />
</h:form>
控制器类(loginController),如下所示:
@ManagedBean @SessionScoped 公共类LoginController {
private Login login;
private LoginTipo loginTipo;
private LoginService service;
public Login getLogin() {
return login;
}
public void setLogin(Login login) {
this.login = login;
}
public LoginService getService() {
return service;
}
public void setService(LoginService service) {
this.service = service;
}
@PostConstruct
public void init()
{
login = new Login();
service = new LoginService();
}
public String login()
{
FacesContext facesCont = FacesContext.getCurrentInstance();
loginTipo = facesCont.getApplication().evaluateExpressionGet(facesCont,
"#{loginTipoController.tipo}", LoginTipo.class);
login = service.login(login.getUsername(), login.getPassword(), loginTipo.getTipo());
if(login.getMensaje_id() != 0)
{
FacesContext.getCurrentInstance().addMessage("usuarioPassword",
new FacesMessage(login.getMensaje()));
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.invalidateSession();
return "";
}
else
{
return login.getMensaje();
}
}
//logout method
public void logout()
{
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.invalidateSession();
try
{
ec.redirect(ec.getRequestContextPath() + "/index.jsf");
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
我没有放置LoginService()类代码,因为它只是转到数据库并检查用户是否存在。我只想知道我需要做什么才能在用户成功登录时存储会话。
请注意,在控制器类的login()方法中,当用户登录失败时,我会显示错误消息。之后,我有以下代码:
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
ec.invalidateSession();
我正在摧毁这次会议。我想避免必须这样做!
答案 0 :(得分:1)
据我所知,您基本上想要在登录失败时清除登录表单。您可以清除表示表单数据的bean属性。
login = new Login();
loginTipo = null;
bean本身不一定需要是会话范围的。它可以是请求作用域,您可以手动将用户对象放入会话中。我理解Login
代表用户。在这种情况下,登录成功后,请执行以下操作:
ec.invalidateSession();
ec.getSessionMap().put("login", login);
return "/userhome?faces-redirect=true";
登录用户将在会话范围内以#{login}
的形式提供。
在登录前明确地使会话无效是一种很好的安全措施,可以避免会话固定攻击。在每次登录失败时使其失效确实是不必要的。