Monday, July 4, 2011

Authentication... finally

Well that took longer then expected, I had hoped to get this over with in one day but unfortunately it took a little longer...

As I am quite lazy and do not like the idea of having to deal with keeping track of user accounts and such I have decided to make my life simple and use Google accounts to login to my site. This means I can use the Google App Engine libraries and save a lot of time working out how to make a really secure login process. After all Google has a lot more people to throw at this kind of thing so I'll trust them to do this the right way.

I am still thinking about using the Scribe libraries by: Pablo Fernandez which would allow me to offer a lot more then just a Google login as possibility but I am not sure yet. I might actually try and roll my own OAuth process just for the heck of it... for not though Google OAuth will have to do.

In the end it was not all that hard to work this all out. First of all I created a simple loginInfo class for the basic house keeping, such as loggedIn, userID, isAdmin, logogInUrl, logoutUrl etc.
The next step is a very basic RPC service with a single call: getLoginInfo() returning thats right the loginInfo class created earlier. On the server side this gets only slightly more exciting as there the actual communication with the Google App Engine is done. Which looks like the below:

 public LoginInfo getLoginInfo(String currentUrl) {

UserService userService = UserServiceFactory.getUserService();

String loginUrl = userService.createLoginURL(currentUrl);
String logoutUrl = userService.createLogoutURL(currentUrl);

User user = userService.getCurrentUser();
String userId = null;
String nick = null;
boolean isAdmin = false;
boolean isLoggedIn = false;
if (user != null) {
userId = user.getUserId();
nick = user.getNickname();
isLoggedIn = userService.isUserLoggedIn();
isAdmin = userService.isUserAdmin();
}

LoginInfo loginData = new LoginData();
loginInfo.setLoginUrl(loginUrl);
loginInfo.setLogoutUrl(logoutUrl);
loginInfo.setUserId(userId);
loginInfo.setNick(nick);
loginInfo.setLoggedIn(isLoggedIn);
loginInfo.setAdmin(isAdmin);

return loginData;
}
Once all that is done the only thing one has to do is provide the user with a link to the Google page: getLoginUrl and once logged in a link to the Google logout page getLogoutUrl and thats all there is to it. From this point on there are hundreds of milions of users that can login to my site without even needing to register for it.

The appeal of adding Yahoo, Facebook, Twitter and several other OAuth login options is of course to get to that magical 1000 billiontrilliongazillion people with an account but realistically at the moment all the site does is say hello world in the 5 languages in which I know how to spell that correctly, which is why for now the couple of hundred million will have to do :)

Tomorrow I'll add a nice form and have my users add data to the site. As I am on Google App Engine I'll see about using the Google data stores for the storing of this data.

Saturday, July 2, 2011

GWT internationalization and cookies

Today I wanted to setup internationalization for a project I'm working on. I decided for various reasons not to use the ?locale=x_y but to use a cookie to allow the user to set the locale, and for the site to remember the users preference. I spend some time trying to figure out how to do this right in GWT, using no additional libraries and avoiding any changes to the GWT generated HTML.

Here is what I came up with:

In my <project>.gwt.xml file I added the following line:
<set-configuration-property name="locale.cookie" value="gwtLocale"/>

On the page I created a simple dropdown box with all the languages supported by my site. I am filling this box with the following code (shamlessly coppied from the GWT Showcase app by Google).
     String[] localeNames = LocaleInfo.getAvailableLocaleNames();
for (String localeName : localeNames) {
if (!localeName.equals("default")) {
String nativeName = LocaleInfo.getLocaleNativeDisplayName(localeName);
languageBox.addItem(nativeName, localeName);
if (localeName.equals(currentLocale)) {
languageBox.setSelectedIndex(languageBox.getItemCount() - 1);
}
}
}
In the change handler for this dropdown box I set up the following bit of code:

  String localeName = languageBox.getValue( languageBox.getSelectedIndex() );

Date now = new Date();
long nowLong = now.getTime();
nowLong = nowLong + (1000 * 60 * 60 * 24 * 21);
now.setTime(nowLong);
Cookies.setCookie("gwtLocale", localeName, now);

Then once the page is reloaded I do the following:
  String currentLocale = Cookies.getCookie( LocaleInfo.getLocaleCookieName() );

if (currentLocale.equals("default") || currentLocale == null ) {
currentLocale = "en_US";
}
And that's it a very simple clean and easy pure GWT way of allowing your user to set their locale for your website using a cookie. Not bad for my first day of playing wit GWT, now on to the next task of the project having a user login on the site. (Authentication only for now Authorization will follow after that...)