GWT 请求基于工厂的身份验证



我第一次尝试GWT RequestFactory(RF(,并尝试实现一个简单的登录屏幕和身份验证系统(没有使用任何花哨的东西,只是在这里摆弄基础知识(。我希望实现的基本用户体验与课程相当:

用户将看到一个登录屏幕(电子邮件和密码以及"登录"按钮(。当他们单击该按钮时,我想使用 RF 将他们的凭据发送到服务器(使用 ValueProxy,因为这些不是实体(并对其进行身份验证。如果凭据正确,他们现在已"登录"到系统,GWT应用程序将下载一个全新的模块,他们将被重定向到其帐户的主菜单。如果凭据不正确,我想发回一个字符串,说明电子邮件或密码不正确,并且它们仍然"注销"了应用程序。

关于我昨天发布的这个问题,我现在已经弄清楚了如何使用 RF 公开一个SignInOutService,该具有用于尝试登录用户的signIn(SignIn)方法,以及用于将用户注销系统的signOut(SignOut)方法。但是现在我实际上正在尝试实现该服务,这是我到目前为止所拥有的:

public class DefaultSignInOutService {
    // Try to sign the user into the system.
    public String signIn(SignIn signIn) {
        // The SignIn object contains the email/hashed password the user tried
        // signing-in with, as well as other metadata I'm looking to store for
        // security purposes (IP address, user agent, etc.).
        String email = signIn.getEmail();
        String hashedPassword = signIn.getHashedPassword();
        // This will be set to a non-null value if the sign-in attempt fails.
        // Otherwise (on successful sign-in) it will stay NULL. The client-side
        // handler will know what to do with the UI based on this value.
        String failReason = null;
        // For this simple example, the password is "12345" and below is it's MD5 hash.
        // Hey! That's the combination on my luggage!
        if(!"skroob@spaceballs.example.com".equals(email) || !"827ccb0eea8a706c4c34a16891f84e7b".equals(hashedPassword))
            failReason = "Login failed; incorrect email or password.";
        else {
            // Log the user into the system...
            // TODO: How?
        }
        return failReason;
    }
    // Sign the user out of the system.
    public void signOut(SignOut signOut) {
        // The SignOut object should reference the user attempting to sign out, as well as a reason
        // for why the sign out is occurring: the user manually requested to be signed out, or they
        // "expired" due to inactivity or navigating the browser away from the app, and so the system
        // auto-signed them out, etc.
        // TODO: How?
        return;
    }
}

所以现在,我已经实现了我的超级简单的电子邮件/密码检查,我已经准备好编写代码,以某种方式将用户登录到应用程序(这样他们就不会一遍又一遍地看到登录屏幕(。我窒息着下一步该做什么。

我正在尝试找到解决方案的问题:

  1. GWT RF 是否以某种方式基于会话或令牌?如果是这样,在注释行" Log the user into the system... "下,我可以写什么代码说">此用户现在已通过身份验证,设置一些 cookie 或会话变量以使其如此!我问这个问题是因为一旦他们登录并被路由到新模块和主菜单,GWT 将需要一种方法来验证此后的每个后续 RF 请求。
  2. signOut()方法需要重置/清除/取消什么才能清除这些 cookie/会话变量?换句话说,我如何实际注销用户,因此,如果他们尝试转到其主菜单的 URL(同样只有在他们登录后才能访问(,他们将被重定向到登录屏幕?
  3. 如何实现 15 分钟的非活动超时,即用户在一定时间长度后自动注销应用?我认为一旦我看到上面的问题 #1 和 #2 是如何工作的,这个答案就会变得更加明显。

有人告诉我,我可能需要两个 servlet 和/或过滤器:一个用于处理未经身份验证的 RF 请求(当用户注销或尚未登录时(,另一个用于处理经过身份验证的 RF 请求(一旦用户主动登录(。但我看不出它们如何融入这里的整体情况。

最简单的方法是在会话中存储身份验证详细信息。

public String signIn(SignIn signIn) {
    ...
    if(!"skroob@spaceballs.example.com".equals(email) || !"827ccb0eea8a706c4c34a16891f84e7b".equals(hashedPassword))
        failReason = "Login failed; incorrect email or password.";
    else {
        RequestFactoryServlet.getThreadLocalRequest().getSession().setAttribute("auth", signIn);
    }
    return failReason;
}
public void signOut(SignOut signOut) {
    RequestFactoryServlet.getThreadLocalRequest().getSession().removeAttribute("auth");
    return;
}

在每个请求中,您可以检查SignIn对象是否仍然存在于会话中:

SignIn signIn = null;
final Object userObject = RequestFactoryServlet.getThreadLocalRequest().getSession().getAttribute("auth");
if (userObject != null && userObject instanceof SignIn) {
  signIn = (SignIn) userObject;
}

如果缺少此对象,则应取消请求并将用户重定向到登录页面。

最新更新