Friday, September 6, 2013

Passing Extra Data to the Server in Flex Login Message

I was tasked with trying to send extra information, the browser's locale to be more specific, to the server during the authentication process of my Flex application.  I am using Granite Data Services for handling remote calls to the web server.

The code to perform the login on the ChannelSet did look like this:
var token:AsyncToken = RemoteObject(service).channelSet.login(user,pwd);
token.addResponder(responder);

The above code will get the ChannelSet from the RemoteObject and calls the login() function on it to retrieve an AsyncToken.  A responder is then added to the token and it is then sent off to the server.

Usually when making calls to the server, outside of login, we just make a call on the RemoteObject for a method defined by the server. If I was dealing with one of those calls I could add a new argument for the locale and be on my way, but for authentication the login function of ChannelSet is set in stone.

So after a little debugging and toying around I found that the AsyncToken contains an IMessage property, which has a headers property.  On the server side I have a class which extends org.granite.spring.security.SpringSecurity3Service that handles the authentication.  From inside that class I can get an instance of the HttpGraniteContext . I found the IMessage object from the AsyncToken was available inside the HttpGraniteContext .  Since it is available on the server sign I simply needed to add a new property to the headers object.

So now the code looks like this:
var token:AsyncToken = RemoteObject(service).channelSet.login(user,pwd);
// Adding the locale to the CommandMessage's headers map.
token.message.headers["myLocaleKey"] = locale;
token.addResponder(responder);

On the server side the new header can be accessed like this:
HttpGraniteContext graniteContext = (HttpGraniteContext)GraniteContext.getCurrentInstance();
graniteContext.getAMFContext().getRequest().getHeader("myLocaleKey")

That's it!