I have an application that uses GWTP, which heavily relies on Gin & Guice. My app authentication works using a CurrentUserDto
to represent the currently logged in user, which is bound to a Provider
and is injected where needed.
My app allows users to login by checking the user's email and password against the datastore and sets a token in the user's cookies if there is a match, to signify being logged in. Pretty basic stuff so far...
The CurrentUserDtoProvider
checks for the cookie on the client, and if it exists and is still valid, returns the CurrentUserDto
with the correct details.
My 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);
}
});
}
}
My problem occurs when my ClientLogin
action returns with the validation token. See above onReturn()
method. Here I would like to simply run the code in onReveal()
again, but as the CurrentUserDto
still says a user is not logged in, the login page is left on the screen.
Refreshing the whole GWT app is the only way I can manage to refresh the details in the CurrentUserDto
entity that was injected into the login page BEFORE the user logged in. What is the best way to do this?
Is there another way to get a fresh copy of the CurrentUserDto?
Is there another way to reload the same page that will cause Gin to @Inject
my constructor again?
Apologies if this is unclear. I am not very experienced with GIN/Guice.
You're setting cookies and forwarding to different URL's. This is not necessary with GWT or GWTP. No need for the classic postback mindset.
Use the @LoggedInGatekeeper on your pages to control access for logged in/out status. Cookies should be set on the server request for auth and cleared on logout request. @LoggedInGatekeeper implementation wired by Gin should track the user object for the current logged in user if you need it.
Here are the steps I use in my apps
On (app) page load
LoggedInGatekeepr will do the rest for you now. If they're requesting an internal page and they are logged out, it will forward them to the specified default place, typically the login screen.
On Login
On Logout
So, again, no need to even touch cookies on the client side. Don't couple your client with the cookies. Cookies add overhead to every request and couple your client and server code. The server knows how to handle sessions, so let it take care of them.