我正在使用JSF 2.0创建一个电影租赁应用程序,Primefaces 3.4.1作为前端。用户注册成功后,我需要使用新创建的ID自动登录并重定向到主页。
目前,我这样做:
@ManagedBean
@ViewScoped
public class RegistrationBean extends BaseBean implements Serializable
{
...
public String register()
{
String nextPage = null;
User userDetails = new User();
try
{
BeanUtils.copyProperties(userDetails, this);
int registrationID = getServiceLocator().getUserService().registerUser(userDetails);
LOGGER.info("Registered user successfully. Registration ID - {}", registrationID);
// auto login
LoginBean loginBean = (LoginBean)FacesUtils.getManagedBean("loginBean");
loginBean.setUserId(userID);
loginBean.setPassword(password);
loginBean.login();
}
catch (Exception e) {
LOGGER.error("Error during registration - " + e.getMessage());
FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, null,
FacesUtils.getValueFromResource(RESOURCE_BUNDLE, REGISTRATION_FAIL));
FacesContext.getCurrentInstance().addMessage(null, message);
}
return nextPage;
}
}
LoginBean :
@ManagedBean
@SessionScoped
public class LoginBean extends BaseBean implements Serializable
{
...
public String login()
{
FacesContext ctx = FacesContext.getCurrentInstance();
try
{
currentUser = getServiceLocator().getUserService().findUser(userID);
if (currentUser == null)
{
ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, null,
FacesUtils.getValueFromResource(RESOURCE_BUNDLE, UNKNOWN_LOGIN)));
return (userID = password = null);
}
else
{
if (EncryptionUtils.compareHash(password, currentUser.getEncrPass())) {
return INDEX + "?faces-redirect=true";
}
else
{
ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, null,
FacesUtils.getValueFromResource(RESOURCE_BUNDLE, AUTH_FAIL)));
return null;
}
}
}
catch (Exception e)
{
final String errorMessage = "Error occured during login - " + e.getMessage();
LOGGER.error(errorMessage);
ctx.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, null, errorMessage));
}
return null;
}
}
register()
方法的上述方法无疑是错误和不安全的。有什么方法可以更清洁地实现同样的目标吗?
RegistrationBean
int registrationID = getServiceLocator().getUserService().registerUser(userDetails);
LOGGER.info("Registered user successfully. Registration ID - {}", registrationID);
nextPage = LOGIN + "?faces-redirect=true&id=" + registrationID;
login.xhtml
<f:metadata>
<f:viewParam name="id" value="#{loginBean.regID}" />
<f:event listener="#{loginBean.autoLogin}" type="preRenderView"></f:event>
</f:metadata>
LoginBean
private int regID;
...
public void autoLogin()
{
if (regID > 0 && !FacesContext.getCurrentInstance().isPostback())
{
currentUser = getServiceLocator().getUserService().findUser(regID);
NavigationHandler navHandler = FacesUtils.getApplication().getNavigationHandler();
navHandler.handleNavigation(FacesContext.getCurrentInstance(), null, INDEX + "?faces-redirect=true");
}
}
答案 0 :(得分:0)
因此,我们假设您有三页
此处成功注册需要自动登录,需要重定向到主页,但通常必须在注册后手动登录。
无论如何,我建议您在facade类中使用单独的方法分隔登录凭据检查,或者也可以在LoginBean中使用它。
public User doLogin(String userName, String password) {
// query user
// match with password
// return null if not found or not matched
}
在navigation-rule
中为注册bean和登录bean添加faces-config.xml
<navigation-case>
<from-outcome>loginSuccess</from-outcome>
<to-view-id>/home.xhtml</to-view-id>
<redirect/>
</navigation-case>
在注册bean和登录bean调用doLogin
方法中,如果用户找到了设置导航
NavigationHandler nh = facesContext.getApplication().getNavigationHandler();
nh.handleNavigation(facesContext, null, "loginSuccess");