Monday, July 30, 2007

Connecting Erlang to Blogger (Part 1) - Auth with ClientLogin

With the Gdata API from google you can connect your application to some nice services... Calendar, Blogger etc.
Since this is completly REST based you can of course use your 'http:request' to connect and exploit those services. Let's begin with the ClientLogin process.

For this article we will focus on the Blogger API, the main purpose is of course create an Erlang client for Blogger :)

Connecting to google is as simple as sending something like this:

accountType=HOSTED_OR_GOOGLE&Email=YOURGOOGLEACOUNT&Passwd=YOURPASSWORD&source=SelfCo-TestApp-1&service=blogger


Now we can do it in Erlang too !. First we need to build the query string, second we need to send it to the ClientLogin service using 'http:request'.


auth(Username, Password, Application) ->
Sep = <<"&">>,
Post = [
<<"accountType=HOSTED_OR_GOOGLE&">>,
<<"Email=">>, list_to_binary(Username), Sep,
<<"Passwd=">>, list_to_binary(Password), Sep,
<<"source=">>, list_to_binary(Application), Sep,
<<"service=blogger">> ],
request(erlang:iolist_to_binary(Post)).



The fun 'erlang:iolist_to_binary/1' transforms the list of binaries to a simple binary, this is not really necessary but this will ease yourself later for debugging...

Now we can send this query string to the google ClientLogin process:

request(Data) ->
case http:request(post,
{"https://www.google.com/accounts/ClientLogin", [],
"application/x-www-form-urlencoded", Data},
[ {timeout, 3000} ], [{stream, "/tmp/google.test"}, {body_format, binary}]) of

{ok, saved_to_file} ->
io:format("Saved to file~n");

{ok, Result} ->
io:format("Received: ~p~n", [Result]);

{error, Reason} ->
io:format("Error: ~p~n", [Reason])
end.


  • This is a POST query
  • The service is https://www.google.com/accounts/ClientLogin
  • The content-type is application/x-www-form-urlencoded
  • We sets the timeout to 3 seconds
  • We store the result (if successful to '/tmp/google.test')


Let's try this code:

65> google:auth("test@gmail.com", "secretcode").
Received: {{"HTTP/1.1",403,"Forbidden"},
[{"cache-control","no-cache"},
{"date","Sun, 29 Jul 2007 20:44:20 GMT"},
{"pragma","no-cache"},
{"server","GFE/1.3"},
{"content-length","24"},
{"content-type","text/plain"}],
<<"Error=BadAuthentication\n">>}
ok

The connection fails, so let's try with a valid user account:

70> google:auth("validaccount@gmail.com", "validpassword").
Saved to file
ok

Success !

The content of '/tmp/google.test':

SID=DQAAAG8AAACuATb7YJxMdqQhp0LIf546SWLfDNfTlANffRc0B6OGbTat4Ebdj89s6hVEzfNZRL...
LSID=DQAAAHEAAAAG1iqBgOrgzrY5cdgpBv9y42HxkvjNuUaYKImw6yH7xh0GtL5EG19C9GkGdPEb1...
Auth=DQAAAHAAAAAG1iqBgOrgzrY5cdgpBv9y42HxkvjNuUaYKImw6yH7xh0GtL5EG19C9GkGdPEb1...


The final token we need is the 'Auth=' one, this string will be passed with every new query as an 'Authorization' header:

Authorization: GoogleLogin auth=DQAAAHAAAA...


Next Time in Part 2, I'll show you how we'll use this AuthToken and how we will be able to post a message to our blog !

No comments:

Sticky