HTTParty Cookies and Devise

Elmo-Cookie-Monster-elmo-2370432-1024-768So you are working in Ruby, you like to party, you like HTTP and you like cookies. For many ruby developers the HTTParty is a great way to make http calls from your ruby code to a web service. When you have an unsecured web service using it is really straight forward. When you are working with secured web services you will need to pass in security credentials. Sometimes it will be a token that is posed as a parameter, sometimes services will require that you set a authentication header and others rely on information being set in cookies.

Why Cookies?

Many services will use a token passed in as a parameter, or in the case of Oauth you will set a Authorization header with various keys. In our case we had a service that allows user to login via Devise and another that handled universal login for a number of services that can use our devise based login as one of many mechanisms for authenticating into our system. The details of that solution are the subject of future post.

In our system the user would log into the devise based system, devise sets a cookie in the user’s browser, then they are redirected to our Oauth system, the Oauth system verifies the credentials by doing a request with the session cookie back to the Devise system, once that comes back successful an Oauth grant is created and a cookie is set in the users browser for use by other web services and the user is redirected to the page they were initially authenticating for.

Devise used to have a token mechanism for authenticating called TokenAuthenticatable, but in more recent versions it has been taken out. Since we already have a browser that has the session cookie, instead of re-inventing the wheel we decided to create a verification endpoint on the devise based system that checks if the user is logged in and sends a success message if they are. Then our Oauth provider can read the cookie, use HTTParty to send a request with it’s cookie to the devise system, verify it and create it’s Oauth grants etc.. But how do you send cookies with HTTParty?

Show Me The Code

Install HTTParty

gem install http-party

The Right Way

If you only need to send the cookie once you can pass it as a cookies parameter to a call. For example if you are performing a get request your request might look like this.

HTTParty.get "http://www.purrprogramming.com", cookies: {cat_password: 'dogs_drool'}

Some Interesting Side Effects

You might be tempted to use HTTParty by including it in your class.

class WildPurrProgrammingParty
  include HTTParty

  def self.perform_session_actions(catnip_cookie_value)  
    self.get 'http://www.purrprogramming.com', cookies: { _catnip_session: catnip_cookie_value}
  end
end

When we run the code.

my_party = WildPurrProgrammingParty.new 'dogs drool'
my_party.perform_session_actions

The cookies passed to the server will look like this.

{"_catnip_session" => "dogs drool"}

But, if you execute the request again the cookies look like this

{"request_method"=>"GET", "_catnip_session"=>"dlpvODRxdlpSQW5Eb3QyeWZ6bHpkUU9qU2FydGJIWllRdVVIbVFqaTdUMVE2eWs1eUdkSHBkR2JtSXBpRy9qZnhUMzljVlM1dVArOU5yRUVJeEY4bkNSM2xucnAzbUxFT2xyb1VobklVd0lIOHZHRDh2aWQvdTF6WTIvZ2U4ajAxTXBndFJmNWRhM3d5N3YzL0RQbVdHTWhCWjhzSzY1K0RBd0twM1l6VmhqckZvVk5TYzhtNEQ1SnFxWUZXc28vQkk4Sm9jK0EyUUNkbm1yNDIyKy84eC9JTEtweU1TZklRa3hKUDMzYkFkaz0tLXk4THJPS2NwaHFERTZkdXV1Q3lUYlE9PQ==--390aeaf728762b133a0543d7b7f7ed811be530c0", "HttpOnly"=>""}

What happened is that the cookies returned from the first request over-wrote the cookies you passed into the get request on the second call. In this scenario no cookies passed into the get command will be set after you make your first call. Because you are calling this on the class level, this actually sets these cookies for all instances of this class.

This is the correct way to do it.

class WildPurrProgrammingParty
  include HTTParty

  def perform_session_actions(catnip_cookie_value)
    self.cookies({ _catnip_session: catnip_cookie_value})  
    self.class.get 'http://www.purrprogramming.com', {}
  end
end

The takeaway from this are that you can set cookies with HTTParty, the safest way is directly calling it from the class but be careful if you do it via a include into your class.

About Me: I am a Atlanta based, mobile/Android/IOS/AngularJS/Ruby developer, polyglot programmer, founder of Polyglot Programming Inc., wearable technology enthusiast and am interested in the internet of things. You will often find me purr programming and I regularly speak at conferences around the world. I am available for hire! More Posts

Follow Me:
TwitterLinkedInGoogle Plus

I am a Atlanta based, mobile/Android/IOS/AngularJS/Ruby developer, polyglot programmer, founder of Polyglot Programming Inc., wearable technology enthusiast and am interested in the internet of things. You will often find me purr programming and I regularly speak at conferences around the world. I am available for hire!

Posted in Architecture, Development, gems, rails, ruby, scaling Tagged with: , , , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *

*