我有一个使用GWTP的应用程序,它严重依赖于Gin&吉斯。我的应用认证使用CurrentUserDto
来表示当前登录的用户,该用户绑定到Provider
并在需要时注入。
我的应用程序允许用户通过检查用户的电子邮件和密码来登录数据存储区,并在用户的cookie中设置一个令牌(如果匹配),表示已登录。到目前为止非常基本的东西......
CurrentUserDtoProvider
检查客户端上的cookie,如果它存在且仍然有效,则返回CurrentUserDto
的正确详细信息。
我的LoginPresenter
:
public class LoginPresenter extends Presenter<LoginPresenter.MyView, LoginPresenter.MyProxy> implements LoginUiHandlers
{
private CurrentUserDto currentUserDto;
public interface MyView extends View, HasUiHandlers<LoginUiHandlers>
{
}
@Title("Login")
@NoGatekeeper
@ProxyStandard
@NameToken(NameTokens.login)
public interface MyProxy extends ProxyPlace<LoginPresenter>
{
}
private DispatchAsync dispatchAsync;
private PlaceManager placeManager;
@Inject
public LoginPresenter(EventBus eventBus, MyView view, MyProxy proxy,
DispatchAsync dispatchAsync, PlaceManager placeManager,
CurrentUserDto currentUserDto)
{
super(eventBus, view, proxy, RevealType.Root);
this.dispatchAsync = dispatchAsync;
this.placeManager = placeManager;
this.currentUserDto = currentUserDto;
getView().setUiHandlers(this);
}
@Override
protected void onReveal()
{
if(currentUserDto.isLoggedIn())
{
System.out.println("User IS logged in - redirecting to main page");
PlaceRequest request = new PlaceRequest.Builder().nameToken(NameTokens.home).build();
placeManager.revealPlace(request, true);
}
else
{
System.out.println("User IS NOT logged in - showing login page");
// do nothing, we are already on the login page
}
}
@Override
public void onLoginClick(final String email, String password)
{
Window.alert("Client logging in as " + email + " with password " + password);
ClientLogin action = new ClientLogin(email, password);
dispatchAsync.execute(action, new AsyncCallbackImpl<ClientLoginResult>()
{
@Override
public void onReturn(ClientLoginResult result)
{
// set the cookie
Cookies.setCookie("usavtoken", result.getToken());
// here I would like to do this:
//placeManager.revealDefaultPlace()
// but instead I have to do this:
// browser refresh workaround, reloads whole app
String newURL = Window.Location.getHref();
Window.Location.assign(newURL);
}
});
}
}
当我的ClientLogin
操作返回验证令牌时,会出现问题。请参阅上面的onReturn()
方法。在这里,我想再次在onReveal()
中运行代码,但由于CurrentUserDto
仍然表示用户未登录,因此登录页面会保留在屏幕上。
刷新整个GWT应用程序是我能够在用户登录之前刷新注入登录页面的CurrentUserDto
实体中刷新细节的唯一方法。最好的方法是什么?< / p>
有没有其他方法可以获得CurrentUserDto的新副本?
还有另一种方法可以重新加载同一页面,这会让Gin再次@Inject
我的构造函数吗?
如果不清楚,请道歉。我对GIN / Guice不太熟悉。
答案 0 :(得分:2)
您正在设置Cookie并转发到不同的网址。 GWT或GWTP不需要这样做。不需要经典的回发心态。
使用网页上的 @LoggedInGatekeeper 来控制登录/退出状态的访问权限。应在服务器请求上设置Cookie以进行身份验证,并在注销请求时清除。由Gin连接的@LoggedInGatekeeper实现应该在需要时跟踪当前登录用户的用户对象。
以下是我在我的应用中使用的步骤
在(app)页面加载
LoggedInGatekeepr现在将为您完成剩下的工作。如果他们要求内部页面并且他们已经注销,它会将它们转发到指定的默认位置,通常是登录屏幕。
登录
退出
所以,再一次,甚至不需要在客户端触摸cookie。不要将您的客户与cookie结合。 Cookie会增加每个请求的开销,并将客户端和服务器代码耦合在一起服务器知道如何处理会话,所以让它来处理它们。
答案 1 :(得分:0)
您应该bind(CurrentUserDto.class).in(Singleton.class)
,并在currentUserDto.setLoggedIn(true)
方法中设置onReturn
。
答案 2 :(得分:0)
不将CurrentUserDto
绑定为Singleton怎么样?你应该在每个currentUserDtoProvider.get()
上获得一个新的实例!
您需要在演示者中注入CurrentUserDtoProvider
,因为他们是单身人士而不是在CurrentUserDto
上保留引用,但在您需要检查登录时始终调用currentUserDtoProvider.get()
用户。
顺便提一下,看一下提供者代码会很有帮助。